问题描述
它适用于 1 行,但在循环遍历多行时出现堆栈溢出错误。
这就是我定义结构的方式。
int main(void) {
typedef struct values{
struct values* Time;
struct values* RESP;
struct values* PLETH;
struct values* II;
struct values* V;
struct values* AVR;
struct values* ABP;
}values;
values array[60000];
这是数据文件的示例
char line[80];
FILE* pointer = fopen("bidmc_04_Signals.csv","r");
fgets(line,60000,pointer);//moves pointer past 1st line
printf(line);
fgets(line,pointer);
printf(line);
int i = 0;
int c = 0;
int row_count = 0;
int row_limit = 60000;
while (row_count < row_limit) {
fgets(line,60,pointer);
char*p = strtok(line,",");
c = 0;
while (p != NULL)
{
if (c == 0)
strcpy(array[i].Time,p);
array[i].Time = malloc(10000);
if (c == 1)
strcpy(array[i].RESP,p);
array[i].RESP = malloc(10000);
if (c == 2)
strcpy(array[i].PLETH,p);
array[i].PLETH = malloc(10000);
if (c == 3)
strcpy(array[i].II,p);
array[i].II = malloc(10000);
if (c == 4)
strcpy(array[i].V,p);
array[i].V = malloc(10000);
if (c == 5)
strcpy(array[i].AVR,p);
array[i].AVR = malloc(10000);
if (c == 6)
strcpy(array[i].ABP,p);
array[i].ABP = malloc(10000);
p = strtok(NULL,");
c++;
}
row_count++;
i++;
}
fclose(pointer);
for (i = 0; i < 60000; i++) {
free(array[i].RESP);
free(array[i].PLETH);
free(array[i].II);
free(array[i].V);
free(array[i].AVR);
free(array[i].ABP);
}
}
如您所见,我尝试使用 malloc() 将数组数据移动到堆,但没有奏效。 如何防止代码出现堆栈溢出错误?
解决方法
使用更多C dynamic memory allocation。
Call stacks 通常限制为 1 兆字节并包含您的 automatic variable。您的调用范围(对于您的 array
)很大,而且您可能有一个 stack overflow。
你需要为你的数组使用 calloc(3) 并将它声明为 value*array;
(当然,改名,它变成了一个指针,而不是一个数组)。
所以
value*ptr = calloc(60000,sizeof(value));
if (!ptr) { perror("calloc failure"); exit(EXIT_FAILURE); };
然后使用 ptr
而不是 array
。请注意 malloc(3) 和 calloc
可能会失败。另请参阅 errno(3) 和 perror(3)。
不要忘记free(ptr)
。
阅读Modern C并从现有开源软件中汲取灵感,
喜欢 GNU make 或 GTK。另请阅读一些 C 标准草案,例如n1570。
还要仔细阅读 C 编译器的文档,例如GCC 和您的调试器,例如GDB。如果您可以使用 GCC,请使用 gcc -Wall -Wextra -g
进行编译以获得多个警告,甚至可能使用 -fanalyzer
和其他选项,例如 -Wstack-usage=2048
考虑使用 valgrind 和 Clang static analyzer。
在 Linux 上,除了 strace(1) 之外,ltrace(1) 或 gdb(1) 可能会有所帮助。您也可以考虑使用 Frama-C。
我有代码可以对 60000 行进行排序......
然后考虑使用 qsort(3) 或 qsort_r
也读一本好的operating system textbook。
附注。您可能对bismon(见this draft report)和RefPerSys感兴趣。在这两种情况下,请通过电子邮件(英语、法语或俄语)与我联系 basile@starynkevitch.net
除了另一个答案之外,这些行(以及其他 5 个类似的集合)
if (c == 0)
strcpy(array[i].Time,p);
array[i].Time = malloc(10000);
缺少大括号,错误的方式,并分配了过多的内存。请改为
if (c == 0) { // indentation alone does not make a code block
array[i].Time = malloc(strlen(p) + 1); // allocate the right amount
strcpy(array[i].Time,p); // AFTER allocation
}
还有这两行
fgets(line,60000,pointer);
...
fgets(line,60,pointer);
应该是
fgets(line,sizeof line,pointer);