0

我的应用程序中有一个接口函数:

void addShopToList(Tshp **shpHead){
    char* name;
    Tshp *newshp = NULL;
    system("cls");
    printf("Name: ");
    scanf("%s[^\n]", &name);
    fflush(stdin);
    newshp = addShp(shpHead,name,NULL);
    if(prompt("Do you want to add some products?")){
        addProductMenu(&newshp);
    }
}

我得到:

Run-Time Check Failure #2 - Stack around the variable 'name' was corrupted.

当我分别触发这些功能时(我的意思是像 addShp() -> 它只是在列表中添加一个新商店),它可以正常工作。我不知道如何解决它:/。

4

2 回答 2

4

name未初始化,因此当您尝试获取未初始化指针的地址时:

scanf("%s[^\n]", &name);

它吐在你身上。所以有两点:

1)char *name = malloc(100); // now it's initialized to something, don't forget to free it later

2)scanf("%s[^\n]", name); // shouldn't use the & for a string in scanf

第三个奖励点:

3)fflush(stdin);不要那样做。stdin根据 C11 标准 §7.21.5.2 第 2 部分,刷新是未定义的行为:

Ifstream 指向一个输出流...... fflush 函数会导致该流的任何未写入数据......被写入文件;否则,行为未定义。

在某些系统上,如您在fflush()的手册页中所见,Linux 就是其中之一,有一个已定义的行为,但它取决于系统,因此您的代码可能不可移植。

于 2013-05-30T18:11:04.463 回答
1

你有两个问题:

第一个是您将指向字符串的指针的地址scanf传递给- 而不是字符串的地址。该scanf调用不知道这一点,因此它开始将数据读取到您传递给它的地址,覆盖存储的内存位置name,以及它之后的内存(newshp)等等......到scanf完成时,谁知道还剩下什么吗?您可以通过删除通话中的&before轻松解决此问题。namescanf

但是随后您偶然发现了另一个重要的问题:当前name是指向谁知道在哪里的指针-它未初始化。无论它指向哪里,它都不是你的记忆。固定调用scanf将覆盖该内存-您不拥有该内存。然后会发生什么?

解决方案是初始化name指向您分配的内存。您可以使用诸如malloc分配一块内存之类的方法来做到这一点,或者,您可以这样分配堆栈上的空间:

// allocate space for 99 characters (plus 1 space for the null-terminator
// and initialize the memory to all null characters.
char name[100] = { 0 }; 

旁注:您应该真正尝试理解当您传递&name而不是传递时发生的事情之间的细微差别nameto scanf。这将是一项非常重要的教学练习,可以帮助您更好地理解指针以及如何将您的代码翻译成机器可以理解的内容。

最后,您不应该调用fflush(stdin),因为这会导致未定义的行为。这是一件坏事。你认为函数调用会实现什么?

于 2013-05-30T18:14:48.570 回答