我似乎无法理解为什么我的程序会因为字符指针的mallocing内存而导致错误。这是我的代码:
我想要实现的是将数据插入到数组中,以后可以通过for循环读取它以插入完全不同的链接列表。但是,这段代码似乎引起了问题?求救!
struct fileData {
char **data;
size_t used;
size_t size;
};
void initData(struct fileData *a, size_t initialSize) {
a->data = malloc(initialSize * sizeof(char));
if(a->data == NULL) {
printf("ERROR: Memory allocation failure!\n");
exit(1);
}
a->used = 0;
a->size = initialSize;
}
void insertLine(struct fileData *a, char *element) {
if(a->used == a->size) {
void *pointer;
a->size *= 2;
pointer = realloc(a->data, a->size * sizeof(char));
if(pointer == NULL) {
freeData(a);
printf("ERROR: Memory allocation failure!\n");
exit(1);
}
a->data = pointer;
}
if(element != NULL) {
printf("size: %ld", sizeof(element));
a->data[a->used++] = malloc(sizeof(element));
if(a->data[a->used++] != NULL)
strcpy(a->data[a->used++], element);
} else
a->data[a->used++] = NULL;
}
void freeData(struct fileData *a) {
size_t i;
/* Free all the copies of the strings */
for (i = 0 ; i < a->used; i++)
free(a->data[i]);
free(a->data);
free(a);
}
Valgrind的结果:
==8224== Invalid write of size 8
==8224== at 0x1000015D7: insertLine (ets_utility.c:129)
==8224== by 0x100001751: readLines (ets_utility.c:149)
==8224== by 0x1000018F3: load_data (ets_utility.c:199)
==8224== by 0x1000010FE: main (ets_main.c:44)
==8224== Address 0x10001d2e8 is 3 bytes after a block of size 5 alloc'd
==8224== at 0x6B1B: malloc (in /usr/local/Cellar/valgrind/3.10.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==8224== by 0x10000146F: initData (ets_utility.c:99)
==8224== by 0x1000018BF: load_data (ets_utility.c:190)
==8224== by 0x1000010FE: main (ets_main.c:44)
==8224==
==8224== Invalid read of size 8
==8224== at 0x1000015F9: insertLine (ets_utility.c:130)
==8224== by 0x100001751: readLines (ets_utility.c:149)
==8224== by 0x1000018F3: load_data (ets_utility.c:199)
==8224== by 0x1000010FE: main (ets_main.c:44)
==8224== Address 0x10001d2f0 is 11 bytes after a block of size 5 alloc'd
==8224== at 0x6B1B: malloc (in /usr/local/Cellar/valgrind/3.10.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==8224== by 0x10000146F: initData (ets_utility.c:99)
==8224== by 0x1000018BF: load_data (ets_utility.c:190)
==8224== by 0x1000010FE: main (ets_main.c:44)
==8224==
==8224== Invalid read of size 8
==8224== at 0x100001625: insertLine (ets_utility.c:131)
==8224== by 0x100001751: readLines (ets_utility.c:149)
==8224== by 0x1000018F3: load_data (ets_utility.c:199)
==8224== by 0x1000010FE: main (ets_main.c:44)
==8224== Address 0x10001d318 is 24 bytes before a block of size 4,096 free'd
==8224== at 0x6F57: free (in /usr/local/Cellar/valgrind/3.10.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==8224== by 0x13E7D2: fclose (in /usr/lib/system/libsystem_c.dylib)
==8224== by 0x100001422: readfile (ets_utility.c:86)
==8224== by 0x1000018C8: load_data (ets_utility.c:193)
==8224== by 0x1000010FE: main (ets_main.c:44)
==8224==
==8224== Invalid write of size 1
==8224== at 0x8C73: memmove$VARIANT$sse3x (in /usr/local/Cellar/valgrind/3.10.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==8224== by 0xDDA1B: __strcpy_chk (in /usr/lib/system/libsystem_c.dylib)
==8224== by 0x100001706: __inline_strcpy_chk (_string.h:94)
==8224== by 0x100001632: insertLine (ets_utility.c:131)
==8224== by 0x100001751: readLines (ets_utility.c:149)
==8224== by 0x1000018F3: load_data (ets_utility.c:199)
==8224== by 0x1000010FE: main (ets_main.c:44)
==8224== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==8224==
==8224==
==8224== Process terminating with default action of signal 11 (SIGSEGV)
==8224== Access not within mapped region at address 0x0
==8224== at 0x8C73: memmove$VARIANT$sse3x (in /usr/local/Cellar/valgrind/3.10.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==8224== by 0xDDA1B: __strcpy_chk (in /usr/lib/system/libsystem_c.dylib)
==8224== by 0x100001706: __inline_strcpy_chk (_string.h:94)
==8224== by 0x100001632: insertLine (ets_utility.c:131)
==8224== by 0x100001751: readLines (ets_utility.c:149)
==8224== by 0x1000018F3: load_data (ets_utility.c:199)
==8224== by 0x1000010FE: main (ets_main.c:44)
感谢您帮助... C:/
还是新手答案 0 :(得分:2)
你有
a->data = malloc(initialSize * sizeof(char));
和
pointer = realloc(a->data, a->size * sizeof(char));
对于您分配malloc
字节的第一个initialSizè
,指针通常是四个或八个字节,因此您只分配了四分之一或八个足够的内存。
您需要使用sizeof(char *)
作为尺寸。