我编写了一个将字符串转换为字符串数组的函数。
测试程序正常工作,直到我用int main()
int main(int argc, char** argv)
控制台:
*** glibc detected *** ./a.out: realloc(): invalid pointer: 0xbfdc6370 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb764eee2]
/lib/i386-linux-gnu/libc.so.6(realloc+0x25d)[0xb765355d]
/lib/i386-linux-gnu/libc.so.6(realloc+0x273)[0xb7653573]
./a.out[0x80485d6]
./a.out[0x80486bf]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75f24d3]
./a.out[0x8048461]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:05 2889457 /home/tg/a.out
08049000-0804a000 r--p 00000000 08:05 2889457 /home/tg/a.out
0804a000-0804b000 rw-p 00001000 08:05 2889457 /home/tg/a.out
085cc000-085ed000 rw-p 00000000 00:00 0 [heap]
b75a5000-b75c1000 r-xp 00000000 08:05 5637044 /lib/i386-linux-gnu/libgcc_s.so.1
b75c1000-b75c2000 r--p 0001b000 08:05 5637044 /lib/i386-linux-gnu/libgcc_s.so.1
b75c2000-b75c3000 rw-p 0001c000 08:05 5637044 /lib/i386-linux-gnu/libgcc_s.so.1
b75d8000-b75d9000 rw-p 00000000 00:00 0
b75d9000-b777c000 r-xp 00000000 08:05 5636109 /lib/i386-linux-gnu/libc-2.15.so
b777c000-b777d000 ---p 001a3000 08:05 5636109 /lib/i386-linux-gnu/libc-2.15.so
b777d000-b777f000 r--p 001a3000 08:05 5636109 /lib/i386-linux-gnu/libc-2.15.so
b777f000-b7780000 rw-p 001a5000 08:05 5636109 /lib/i386-linux-gnu/libc-2.15.so
b7780000-b7783000 rw-p 00000000 00:00 0
b7797000-b779a000 rw-p 00000000 00:00 0
b779a000-b779b000 r-xp 00000000 00:00 0 [vdso]
b779b000-b77bb000 r-xp 00000000 08:05 5636227 /lib/i386-linux-gnu/ld-2.15.so
b77bb000-b77bc000 r--p 0001f000 08:05 5636227 /lib/i386-linux-gnu/ld-2.15.so
b77bc000-b77bd000 rw-p 00020000 08:05 5636227 /lib/i386-linux-gnu/ld-2.15.so
bfda7000-bfdc8000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
代码:
/* tokenize function*/
int tokenize(char ***tokenList, char *string, char *separators){
/* initialization */
int count = 0; // token counter
int length = strlen(string) + 1; // length of string array
int lengthSep = strlen(separators); // number of separators
char *memory = malloc(length); // copy of string; string token array in the end
if (memory == NULL) // error treatment for malloc
return -1;
memcpy(memory, string, length);
char *lastPos = memory; // start position of the current string token in memory
char **tempList; // temporary pointer to token array
/* find occurences of separators and replace them with '\0', reallocate tempList for each new string token built in that way */
for (int i = 0; i < length; i++){
/* check if current character is a separator */
for (int j = 0; j <= lengthSep; j++){
if (*(memory + i) == separators[j]){
count++; // increase string counter
*(memory + i) = '\0'; // replace separator by '\0'
tempList = realloc(tempList, sizeof(char*) * count); // reallocate tempList
if (tempList == NULL){ // error treatment for realloc
free(memory);
free(tempList);
return -1;
}
tempList[count-1] = lastPos; // add pointer to the new string to the end of tempList
lastPos = memory + i + 1; // calculate starting position for the next string token
break; // escape from inner loop (found matching separator)
}
}
}
*tokenList = tempList;
return count;
}
int main(){
char string[100] = "aa/bbb/cccc";
char separators[2] = "/";
char **tokenList;
int count;
count = tokenize(&tokenList,string, separators);
printf("count: %d\n", count);
printf("item: %s\n", tokenList[0]);
return EXIT_SUCCESS;
}
答案 0 :(得分:12)
您没有初始化tempList
,因此第一次拨打tempList = realloc(tempList,...
时,您试图扩展/释放任意地址。
最简单的解决方法是将tempList
初始化为NULL
char **tempList = NULL;
除此之外,代码
tempList = realloc(tempList, sizeof(char*) * count);
if (tempList == NULL){
free(memory);
free(tempList);
return -1;
}
包含另一个小错误。如果realloc
失败且tempList
为NULL
,则您已泄露之前的tempList
值,并且调用free(tempList)
不执行任何操作。如果要正确处理内存不足错误,则需要执行类似
void* tmp = realloc(tempList, sizeof(char*) * count);
if (tmp == NULL){
free(memory);
free(tempList);
return -1;
}
tempList = tmp;
答案 1 :(得分:5)
templist
未初始化,因此它包含堆栈中声明它的垃圾。
然后将其传递给realloc()
以调整其指向的内存大小。但是realloc()
意识到它并没有指出任何有效的东西。