每次调用函数时,如何创建一个新的字符串用作键?

时间:2019-11-28 07:21:22

标签: c

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

这是我问过的上一个问题,但建议创建一个新问题。 How to avoid retaining string values in C in function calls

在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语言中,我不能将更新的用户用作键,因为如果我在新的函数调用中修改了更新的键,那么从先前的调用中创建的所有键都会更改。

我想问一下如何在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();
    }
}

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

首次通话结果: {'':'stuff0'}

第二次通话结果: {'hihi':'stuff0','hihi':'stuff1'}

第三次通话结果: {'hihi':'stuff0','hihi':'stuff1','hihi':'stuff2'}

1 个答案:

答案 0 :(得分:2)

似乎您只将指针存储到地图中的键上。

您需要存储密钥的副本,但是仅在发生哈希冲突的情况下使用。存储密钥副本的一种方法是使用非标准但普遍可用的strdup函数。


使用指针指向地图中的键会带来除您看到的问题以外的其他问题。特别是考虑到在您显示的代码中,您对密钥使用了 local 数组,这意味着一旦函数new返回并且newer终止其生命,指针将变得无效。

在显示的代码中,您还可以在newer初始化之前打印其内容,并且其内容为 indeterminate

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

对于该阵列,您还使用了接近4 MiB的内存,并且考虑到编译器会将其放置在非常有限的堆栈上,因此会浪费很多空间(更不用说您的程序将无法在默认堆栈的Windows上运行只是一个MiB)。