#include<stdio.h>
#include<stdlib.h>
void func(char *p[],int);
void main()
{
char **strings;
int r;
printf("\nEnter the no. of rows :");
scanf("%d",&r);
strings=malloc(r*sizeof(strings));
func(strings,r);
printf("%s %s\n", strings[0], strings[1]);
}
void func(char *p[],int r)
{
int i;
for(i=0;i<r;i++)
scanf("%s",p[i]);
}
此代码不超过3个输入...在3个输入之后,它突然停止。
为什么malloc无法正常工作?是不是因为malloc?
答案 0 :(得分:4)
问题在于您如何使用malloc
。你没有分配足够的内存,你也不知道要分配多少内存。
strings=malloc(r*sizeof(strings));
这为strings
字符指针在r
中分配了足够的内存。 strings
现在可以安全地存储r
类型的char *
个变量。麻烦的是你永远不会为strings
中存储的字符串分配内存。
void func(char *p[],int r)
{
int i;
for(i=0;i<r;i++)
/* At this point, p[i] is unallocated */
scanf("%s",p[i]);
}
p[i]
,实际存储字符串的东西也必须分配。多少?谁知道,您正在使用scanf
阅读输入内容。因此,首先剪切是分配一个固定的大小,并且最多只读取那个大小(因为空字符而少一个)。
void func(char *p[],int r)
{
int i;
for( i=0; i < r; i++ ) {
p[i] = malloc( 256 * sizeof(char) );
scanf("%255s",p[i]);
}
}
绝不使用scanf %s
没有最大长度 ,否则输入可能会大于您分配的内存。同样don't use scanf
,如果输入与您的模式不匹配,它会让您遇到麻烦。如果需要,最好使用getline
或fgets
然后sscanf
阅读整行。
在C语言编码时,内存检查器是绝对必要的。它会为您找到这些问题。我使用valgrind。
Enter the no. of rows :5
foo
==10082== Use of uninitialised value of size 8
==10082== at 0x1001F2121: __svfscanf_l (in /usr/lib/system/libsystem_c.dylib)
==10082== by 0x1001EA979: scanf (in /usr/lib/system/libsystem_c.dylib)
==10082== by 0x100000F2B: func (test.c:19)
==10082== by 0x100000EBD: main (test.c:11)
==10082==
==10082== Invalid write of size 1
==10082== at 0x1001F2121: __svfscanf_l (in /usr/lib/system/libsystem_c.dylib)
==10082== by 0x1001EA979: scanf (in /usr/lib/system/libsystem_c.dylib)
==10082== by 0x100000F2B: func (test.c:19)
==10082== by 0x100000EBD: main (test.c:11)
==10082== Address 0x0 is not stack'd, malloc'd or (recently) free'd
这些是指向内存问题的堆栈跟踪。 &#34;使用未初始化的大小为8&#34;告诉我,我没有为字符串分配内存。堆栈告诉我它是scanf
中的func
。