我正在尝试在C中编写一个程序,它接受一个输入流并根据字符串中空格的出现中断输入,并从中创建一个二维数组。 e.g。
如果输入为:
this is cat
输出:
this
is
cat
我的代码如下:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
int main(){
int ** a;
int * element;
int i;
int size = 2;
int element_size = 2;
int element_count = 0;
char c;
int flag = 0;
if((a = (int **)calloc(size, sizeof(int **))) == NULL){
printf("Not enough space");
exit(0);
}
for(i = 0; i <= size; i++){
element_size = 2;
element_count = 0;
flag = 0;
if(i >= size){
size *= 2;
if((a = (int **)realloc(size, sizeof(int **))) == NULL){
printf("Not enough space");
exit(0);
}
}
if((element = (int *)calloc(element_size, sizeof(int *))) == NULL){
printf("Not enough space");
exit(0);
}
while(1){
c = getchar();
if(element_count >= element_size){
element_size *= 2;
if((element = (int *)realloc(element_size, sizeof(int *))) == NULL);
}
if(c == ' '){
flag = 0;
break;
}
else if(c == '\n' || c == '\0' || c == '\r'){
flag = 1;
break;
}
else{
element[element_count] = (char)c;
element_count++;
}
}
element[element_count] = '\0';
*a[i] = element;
if(flag == 1)break;
}
for( i = 0; i < size; i++){
printf("%s\n", *a[i]);
}
return 0;
}
此代码使用coredump提供运行时错误SIGSEV
。
使用gdb分析核心转储显示:
Program terminated with signal SIGSEGV, Segmentation fault. #0 __GI___libc_realloc (oldmem=0x4, bytes=8) at malloc.c:2977
2977 malloc.c: No such file or directory.
这个错误是什么意思?
如果可以在我的代码或任何新方法中指出错误,那将非常有用。
答案 0 :(得分:1)
for(i = 0; i <= size; i++)
应该是
for(i = 0; i < size; i++)
和
a = (int **)calloc(size, sizeof(int **)))
应该是
a = calloc(size, sizeof(int *)))
使用i<=size
您正在访问越界并且具有未定义的行为。
int **a
是一个指向指针的整数指针,你需要为指针分配内存int *
答案 1 :(得分:0)
你有realloc
的两个电话,但都错了。 realloc
的第一个参数是指向要重新分配的内存区域的指针,第二个参数是的大小。
这与calloc
的论点完全不同。请注意,realloc
不会清除新内存。如果需要清除额外分配的内存,则应自行清除。如果没有,calloc
可能会由malloc
取代,但这取决于您。
我认为你的编译器警告过你。编译时,您应该看到这样的警告:(当然使用不同的文件名)
badrealloc.c: In function ‘main’:
badrealloc.c:25:9: warning: passing argument 1 of ‘realloc’ makes pointer from integer without a cast [enabled by default]
if((a = (int **)realloc(size, sizeof(int **))) == NULL){
顺便说一下,第58行触发了另一个重要警告。
在C中,没有必要显式地转换alloc函数的返回,很多人(包括我)会建议你不要这样做。此外,通常最好在所需类型的值上使用sizeof
,而不是尝试自己计算出类型,这很容易出错。 (例如,您对realloc
和calloc
的两次调用都会出错。
所以我建议:
if((a = realloc(a, size * sizeof *a))) == NULL)
但是,上面的内容确实不正确,因为当realloc失败时会导致内存泄漏。你应该做什么:
{ void* tmp = realloc(a, size * sizeof *a);
if (tmp) { a = tmp; }
else {
free(a); /* Avoid the memory leak */
/* Handle the error */
}
}
答案 2 :(得分:0)
对我来说,最重要的是malloc包含在stdlib.h中;没有像malloc.h这样的标题。如果你删除标题声明,你应该更好。
H @ ppy&lt; 0d | ^ g!