2013-05-30 77 views
0

我有一个接口功能在我的应用程序:运行时检查失败#2 - 围绕堆栈变量“名称”已损坏

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

name未初始化,所以后来当你尝试走未初始化的指针的地址:

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

它pukes你。所以两点:

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函数导致该流的任何未写入的数据...将被写入到所述文件; 否则,行为是不确定的。

在某些系统,Linux是一个你可以在手册页看到fflush(),有一个定义的行为,但它依赖系统使你的代码可能无法移植。

+0

工作!谢谢 :) – tomdavies

1

你有两个问题:

首先是要传递指针的地址到字符串scanf - 字符串的不是地址。由于scanf调用并不知道,所以它开始读取数据到您通过它的地址,覆盖存储位置name存储在内存中它(newshp)等等...到时候scanf已完成,谁知道剩下的是什么?您可以通过在scanf调用中的name之前删除&来轻松解决该问题。

但是后来你偶然发现了另一个重要的问题:目前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而不是namescanf会发生什么情况。这将是一个非常重要的教学练习,帮助您更好地理解指针以及代码如何转换为机器可以理解的内容。

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

相关问题