我的应用程序中有一个接口函数:
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() - >它只是在列表中添加一个新商店),它可以正常工作。 我不知道如何解决它:/。
答案 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)
,因为这会导致未定义的行为。这是一件坏事。您认为函数调用会如何实现?