gpt4 book ai didi

c - "Pointer being freed was not allocated"发生在 mac 但不是在 windows 7

转载 作者:行者123 更新时间:2023-12-01 01:48:48 25 4
gpt4 key购买 nike

我正在做一本书的练习,将句子中的单词改成 pig latin。代码在window 7下运行正常,但是当我在mac上编译时,错误就出来了。

经过一些测试,错误来自那里。我不明白这个问题的原因。我为所有指针使用动态内存,并且还添加了空指针检查。

while (walker != NULL && *walker != NULL){
free(**walker);
free(*walker);
free(walker);

walker++;
}

完整源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define inputSize 81
void getSentence(char sentence [], int size);
int countWord(char sentence[]);
char ***parseSentence(char sentence[], int *count);
char *translate(char *world);
char *translateSentence(char ***words, int count);

int main(void){
/* Local definition*/
char sentence[inputSize];
int wordsCnt;
char ***head;
char *result;

getSentence(sentence, inputSize);
head = parseSentence(sentence, &wordsCnt);

result = translateSentence(head, wordsCnt);
printf("\nFinish the translation: \n");
printf("%s", result);


return 0;
}

void getSentence(char sentence [81], int size){
char *input = (char *)malloc(size);
int length;

printf("Input the sentence to big latin : ");
fflush(stdout);
fgets(input, size, stdin);

// do not copy the return character at inedx of length - 1
// add back delimater
length = strlen(input);
strncpy(sentence, input, length-1);
sentence[length-1]='\0';

free(input);
}

int countWord(char sentence[]){
int count=0;

/*Copy string for counting */
int length = strlen(sentence);
char *temp = (char *)malloc(length+1);
strcpy(temp, sentence);

/* Counting */
char *pToken = strtok(temp, " ");
char *last = NULL;
assert(pToken == temp);
while (pToken){
count++;

pToken = strtok(NULL, " ");
}

free(temp);
return count;
}
char ***parseSentence(char sentence[], int *count){
// parse the sentence into string tokens
// save string tokens as a array
// and assign the first one element to the head
char *pToken;
char ***words;
char *pW;

int noWords = countWord(sentence);
*count = noWords;

/* Initiaze array */
int i;
words = (char ***)calloc(noWords+1, sizeof(char **));
for (i = 0; i< noWords; i++){
words[i] = (char **)malloc(sizeof(char *));
}

/* Parse string */
// first element
pToken = strtok(sentence, " ");

if (pToken){
pW = (char *)malloc(strlen(pToken)+1);
strcpy(pW, pToken);
**words = pW;
/***words = pToken;*/

// other elements
for (i=1; i<noWords; i++){
pToken = strtok(NULL, " ");
pW = (char *)malloc(strlen(pToken)+1);
strcpy(pW, pToken);
**(words + i) = pW;
/***(words + i) = pToken;*/
}
}

/* Loop control */
words[noWords] = NULL;


return words;
}

/* Translate a world into big latin */
char *translate(char *word){
int length = strlen(word);
char *bigLatin = (char *)malloc(length+3);

/* translate the word into pig latin */
static char *vowel = "AEIOUaeiou";
char *matchLetter;
matchLetter = strchr(vowel, *word);
// consonant
if (matchLetter == NULL){
// copy the letter except the head
// length = lenght of string without delimiter
// cat the head and add ay
// this will copy the delimater,
strncpy(bigLatin, word+1, length);
strncat(bigLatin, word, 1);
strcat(bigLatin, "ay");
}
// vowel
else {
// just append "ay"
strcpy(bigLatin, word);
strcat(bigLatin, "ay");
}


return bigLatin;
}

char *translateSentence(char ***words, int count){
char *bigLatinSentence;
int length = 0;
char *bigLatinWord;

/* calculate the sum of the length of the words */
char ***walker = words;
while (*walker){
length += strlen(**walker);
walker++;
}

/* allocate space for return string */
// one space between 2 words
// numbers of space required =
// length of words
// + (no. of words * of a spaces (1) -1 )
// + delimater
// + (no. of words * ay (2) )
int lengthOfResult = length + count + (count * 2);
bigLatinSentence = (char *)malloc(lengthOfResult);
// trick to initialize the first memory
strcpy(bigLatinSentence, "");

/* Translate each word */
int i;
char *w;
for (i=0; i<count; i++){
w = translate(**(words + i));
strcat(bigLatinSentence, w);
strcat(bigLatinSentence, " ");
assert(w != **(words + i));
free(w);
}


/* free memory of big latin words */
walker = words;
while (walker != NULL && *walker != NULL){
free(**walker);
free(*walker);
free(walker);

walker++;
}

return bigLatinSentence;
}

最佳答案

你的代码不必要地复杂,因为你已经设置了这样的东西:

  • n : 字数
  • words : 指向可以容纳 n+1 的已分配内存char **按顺序值
  • words[i] ( 0 <= i && i < n ): 指向可以容纳一个 char * 的已分配内存按顺序
  • words[n] : NULL
  • words[i][0] : 指向为单词分配的内存(和以前一样,0 <= i < n)

因为每个words[i]指向顺序的东西,有一个words[i][j]对于一些有效的整数 j ... 但是 j 的允许值始终为 0,因为只有一个 char * malloc() 在那里。所以你可以完全消除这种间接级别,只需要 char **words .

但这不是问题所在。释放循环以 walker 开始与 words 相同, 所以它首先尝试释放 words[0][0] (这很好并且有效),然后尝试释放 words[0] (这很好并且有效),然后尝试释放 words (这很好并且有效,但意味着您不能再访问任何其他 words[i] 以获得 i 的任何值——即“存储泄漏”)。然后它增加 walker , 使其或多或少等同于 &words[1] ;但是words已经free() d.

而不是使用 walker在这里,我将使用带有一些整数的循环 i :

for (i = 0; words[i] != NULL; i++) {
free(words[i][0]);
free(words[i]);
}
free(words);

我还建议删除所有 malloc() 上的强制转换和 calloc()返回值。如果您在执行此操作后收到编译器警告,它们通常意味着以下两种情况之一:

  • 你忘了#include <stdlib.h> , 或
  • 您正在对您的 C 代码调用 C++ 编译器。

后者有时有效,但却是痛苦的根源:好的 C 代码是坏的 C++ 代码,好的 C++ 代码不是 C 代码。 :-)


编辑:PS:我错过了差一 lengthOfResult @David RF 捕获了。

关于c - "Pointer being freed was not allocated"发生在 mac 但不是在 windows 7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17891538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com