运行时检查失败#2 - 变量'name'周围的堆栈已损坏

时间:2013-05-30 18:07:19

标签: c visual-studio-2010

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

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() - >它只是在列表中添加一个新商店),它可以正常工作。 我不知道如何解决它:/。

2 个答案:

答案 0 :(得分: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);不这样做。根据C11标准§7.21.5.2第2部分,刷新stdin是未定义的行为:

  

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

在某些系统上,正如您在fflush()的手册页中看到的那样Linux是一个系统,它有一个已定义的行为,但它依赖于系统,因此您的代码可能无法移植。

答案 1 :(得分:1)

你有两个问题:

首先,您将指向字符串的指针的地址传递给scanf - 而不是字符串的地址。 scanf调用不知道,因此它开始将数据读入您传递的地址,覆盖存储name的内存位置,之后的内存它(newshp)等等......到scanf完成时,谁知道还剩下什么?您可以通过移除&来电中name之前的scanf轻松解决此问题。

然后你偶然发现另一个重要的问题:目前name是一个指向 who-know-where 的指针 - 它未初始化。无论它指向哪里,都不是你的记忆。对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而不是name传递给scanf时所发生的细微差别。这将是一个非常重要的教学练习,可以帮助您更好地理解指针以及如何将代码转换为机器理解的内容。

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