首页 > 解决方案 > 每次调用函数时如何创建新字符串以用作键?

问题描述

由于学校规定,我无法在 C 中发布我的项目代码。

这是我之前提出的一个问题,但建议创建一个新问题。 如何避免在函数调用中保留 C 中的字符串值

在 python 中,我可以执行以下操作,因为每次我调用 newer 时,它都是一个新变量,与之前调用中的 newer 没有关系。

def new(i,diction):
    newer = "hi" * i
    diction[newer] = "stuff" + str(i)


diction = {}
for i in range(3):
    new(i,diction)

print(diction)

本质上,期望的结果是 {'': 'stuff0', 'hi': 'stuff1', 'hihi': 'stuff2'}

但是在 C 中,我不能使用 newer 作为键,因为如果我在新函数调用中修改 newer,那么我从以前的调用创建的所有键都会改变。

我想问如何在 C 中做我在 python 中做的同样的事情。

当我提到在 C 中修改更新时,这就是我的意思。

#include <stdio.h>
#include <string.h>
void new(){
    char  newer[4000000];
    printf("%s\n", newer);
    strncat(newer,"hi",1235);
    //use newer as a key to a hashmap.

}
int main()
{
    int i = 0;
    for (i = 0; i < 3; i++){
        new();
    }
}

每次我更新时,我的 hashmap 中的所有键都会改变。所以这里是我在 C 中的 hashmap 在每次函数调用后的样子

第一次调用结果:{'': 'stuff0'}

第二次调用结果:{'hihi': 'stuff0','hihi': 'stuff1'}

第三次调用结果:{'hihi': 'stuff0', 'hihi': 'stuff1', 'hihi': 'stuff2'}

标签: c

解决方案


看来您只存储指向地图中键的指针。

您需要存储密钥的副本,但仅在哈希冲突的情况下使用它。存储密钥副本的一种方法是使用非标准但常用的strdup功能。


除了您看到的问题之外,使用指向地图中键的指针会带来其他问题。特别是考虑到在您展示的代码中,您使用本地数组作为键,这意味着一旦函数new返回并newer结束其生命,指针将变为无效。

同样在您展示的代码中,您newer在初始化之前打印了它的内容,并且它的内容是indeterminate

这个未初始化的内容newer对于调用也是有问题的strncat,因为它将搜索终止符以知道在哪里附加字符串。从理论上讲,这可能导致函数在该搜索中超出数组的范围。如果您只想将字符串复制到newer使用strcpy中。

您还为数组使用了接近 4 MiB,并且考虑到编译器会将其放在非常有限的堆栈上,您会浪费大量空间(更不用说您的程序不会在默认堆栈仅为单个 MiB)。


推荐阅读