这真的很奇怪......我无法调试它(尝试了大约两个小时,调试器在一段时间后开始失控......)。无论如何,我正在尝试做一些非常简单的事情:
Free an array of strings
. 数组形式为:
char **myStrings
. 数组元素初始化为:
myString[index] = malloc(strlen(word));
myString[index] = word;
我正在调用这样的函数:
free_memory(myStrings, size);
其中 size 是数组的长度(我知道这不是问题,我对它进行了广泛的测试,除了这个函数之外的所有东西都可以工作)。
free_memory
看起来像这样:
void free_memory(char **list, int size) {
for (int i = 0; i < size; i ++) {
free(list[i]);
}
free(list);
}
现在奇怪的部分来了。if (size> strlen(list[i]))
然后程序崩溃。例如,假设我有一个看起来像这样的字符串列表:
myStrings[0] = "Some";
myStrings[1] = "random";
myStrings[2] = "strings";
因此这个数组的长度是3
。
如果我将它传递给我的free_memory
函数strlen(myStrings[0]) > 3
(4 > 3),程序就会崩溃。
但是,如果我改为myStrings[0]
改为"So"
,则strlen(myStrings[0]) < 3
( 2 < 3 ) 并且程序不会崩溃。
所以在我看来,free(list[i])
实际上char[]
是在通过那个位置并试图释放每个角色,我认为这是未定义的行为。
我这么说的唯一原因是因为我可以玩弄第一个元素的大小,myStrings
并在我喜欢的时候让程序崩溃,所以我假设这是问题区域。
注意:我确实尝试通过单步执行调用的函数来调试它free_memory
,注意到任何奇怪的值等,但是当我踏入free_memory
函数的那一刻,调试器崩溃了,所以我不确定发生了什么。在我进入函数之前,没有什么不寻常的,然后世界就爆炸了。
另一个注意事项:我还在此处发布了该程序源代码的缩短版本(不太长;Pastebin)。我正在使用 c99 标志在 MinGW 上编译。
PS-我只是想到了这一点。我确实传递numUniqueWords
给了 free 函数,我知道这实际上并没有释放我分配的整个内存。我已经把它称为两种方式,这不是问题。我把它按照我的做法留下了,因为这是我首先让它工作后调用它的方式,我需要修改我在那个函数中的一些逻辑。
来源,根据要求(现场):
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "words.h"
int getNumUniqueWords(char text[], int size);
int main(int argc, char* argv[]) {
setvbuf(stdout, NULL, 4, _IONBF); // For Eclipse... stupid bug. --> does NOT affect the program, just the output to console!
int nbr_words;
char text[] = "Some - \"text, a stdin\". We'll have! also repeat? We'll also have a repeat!";
int length = sizeof(text);
nbr_words = getNumUniqueWords(text, length);
return 0;
}
void free_memory(char **list, int size) {
for (int i = 0; i < size; i ++) {
// You can see that printing the values is fine, as long as free is not called.
// When free is called, the program will crash if (size > strlen(list[i]))
//printf("Wanna free value %d w/len of %d: %s\n", i, strlen(list[i]), list[i]);
free(list[i]);
}
free(list);
}
int getNumUniqueWords(char text[], int length) {
int numTotalWords = 0;
char *word;
printf("Length: %d characters\n", length);
char totalWords[length];
strcpy(totalWords, text);
word = strtok(totalWords, " ,.-!?()\"0123456789");
while (word != NULL) {
numTotalWords ++;
printf("%s\n", word);
word = strtok(NULL, " ,.-!?()\"0123456789");
}
printf("Looks like we counted %d total words\n\n", numTotalWords);
char *uniqueWords[numTotalWords];
char *tempWord;
int wordAlreadyExists = 0;
int numUniqueWords = 0;
char totalWordsCopy[length];
strcpy(totalWordsCopy, text);
for (int i = 0; i < numTotalWords; i++) {
uniqueWords[i] = NULL;
}
// Tokenize until all the text is consumed.
word = strtok(totalWordsCopy, " ,.-!?()\"0123456789");
while (word != NULL) {
// Look through the word list for the current token.
for (int j = 0; j < numTotalWords; j ++) {
// Just for clarity, no real meaning.
tempWord = uniqueWords[j];
// The word list is either empty or the current token is not in the list.
if (tempWord == NULL) {
break;
}
//printf("Comparing (%s) with (%s)\n", tempWord, word);
// If the current token is the same as the current element in the word list, mark and break
if (strcmp(tempWord, word) == 0) {
printf("\nDuplicate: (%s)\n\n", word);
wordAlreadyExists = 1;
break;
}
}
// Word does not exist, add it to the array.
if (!wordAlreadyExists) {
uniqueWords[numUniqueWords] = malloc(strlen(word));
uniqueWords[numUniqueWords] = word;
numUniqueWords ++;
printf("Unique: %s\n", word);
}
// Reset flags and continue.
wordAlreadyExists = 0;
word = strtok(NULL, " ,.-!?()\"0123456789");
}
// Print out the array just for funsies - make sure it's working properly.
for (int x = 0; x <numUniqueWords; x++) {
printf("Unique list %d: %s\n", x, uniqueWords[x]);
}
printf("\nNumber of unique words: %d\n\n", numUniqueWords);
// Right below is where things start to suck.
free_memory(uniqueWords, numUniqueWords);
return numUniqueWords;
}