函数getFree()
我在一个类似问题的答案中看到过它,但是字符串cpy
仍然具有第一次给定的相同字符串,它运行的次数即T次。所以,请有人帮帮我。
void getFree(char ** ptr) {
if (*ptr != NULL) {
free(*ptr);
}
return;
}
int main() {
int T, j;
scanf("%d", &T);
for (j = 0; j < T; j++) {
char * cpy,
int count = 0, i = 0, x = 0, k = 0;
cpy = (char*)malloc(500 * sizeof(char));
if (getchar() == 'n') {
do {
*(cpy + i) = getchar();
i++;
} while(*(cpy + i - 1) != 'n');
}
getFree(&cpy);
printf("%s", cpy);
}
return 0;
}
Free使指针无效,但不改变指针的值。如果你想要的话,你应该把它归零。在释放它之后,它所指向的对象是未定义的,但是在它被重用之前很可能包含其中的最后一个内容。
free(*ptr);
*ptr = NULL;
您可以考虑将getFree
设置为宏(作为Robert Jacobs回答精神的替代方案),如
#define GET_FREE_AT_BIS(Lin,PtrVar) do {
void**ptr_##Lin = (void**) &(PtrVar);
if (*ptr_##Lin) free (*ptr_##Lin);
*ptr_##Lin = NULL;
} while(0)
#define GET_FREE_AT(Lin,PtrVar) GET_FREE_AT_BIS(Lin,PtrVar)
#define GET_FREE(PtrVar) GET_FREE_AT(__LINE__,(PtrVar))
要使__LINE__
得到扩展,并适合于宏级联,需要双重间接。它用于具有某种独特的变量名,例如123行宏调用的ptr_123
(为了简化调试,并且通常避免与名为ptr
的变量冲突)
然后代码
GET_FREE(cpy);
没有任何可见的地址操作符(在宏展开中完成)。
我的宏应该工作,即使调用GET_FREE(ptrarr[i++]);
,但一个更简单,但错误的变体,如
#define GET_FREE_BUGGY(PtrVar) do { free(PtrVar); PtrVar=NULL; } while(0)
作为GET_FREE_BUGGY(ptrarr[i++]);
调用时不会像人们期望的那样工作,因为i
会增加两次。
如果free
没有像您建议的那样释放内存,那么随后对malloc
的调用将不得不返回一个不同的地址。请注意,参数没有改变,只是在free
返回后访问它的未定义行为。
这只是因为free
实际上释放了内存,当你请求相同数量的内存时,对malloc
的后续调用可以(并且确实)返回相同的地址。
为什么不呢?这实际上是最优行为。如果您只关心(重新)分配的内存的内容- free
和malloc
都不会告诉您那里有什么。由于对内容没有保证或要求,他们决定不去管它。
如果你想要你的内存归零,使用calloc
或memset
或其他东西代替。否则,请放松,不要再假设未初始化的内存中应该有什么。
对于您的特殊情况,不需要在每次循环迭代中重新分配字符串。考虑这个
#include <stdio.h>
#include <stdlib.h>
int main() {
char * cpy = malloc(500); // Allocate in the beginning
int T, i;
scanf("%dn", &T); // Clear newline buffer
while (T--) {
// for (i = 0; (cpy[i] = getchar()) != 'n'; ++i); // Scan until newline
fgets(cpy, 499, stdin); // Scan until newline
printf("%s", cpy);
}
free(cpy); // Free in the end
return 0;
}
输入3
abcde
fghij
klmno
abcde
fghij
klmno
查看演示http://ideone.com/KKEz0j