问题描述
void test(){
char *c = malloc(strlen("I like coffe") + 1);
strcpy(c, "I like coffe");
char **s = &c;
while(strlen(*s) < 25)
my_function(s);
}
void my_function(char **s){
char *w = *s;
char *tmp = realloc(w, len + 2);//Error HERE. *s gets = ""
if(tmp != NULL)
w = tmp;
for(i= len; i>=p; i--){
w[i+1] = w[i];
}
w[p] = c;
}
该函数用于在char *
中插入一个新字符.
此外,这个函数在一个 while 循环中.它工作正常,但到循环运行第三次时,它只设置 *s = ""
.
我认为通过使用 char *tmp
我可以在发生任何错误时保留数据.我不明白为什么 P *s
被设置为空字符串.
This function is used to insert a new character inside a char *
.
Also, this function is inside a while loop. It works fine but by the 3rd time the loop runs, it just sets *s = ""
.
I thought that by using the char *tmp
I could keep the data if any wrong thing happen. I can't understand why P *s
is been setted to empty string.
推荐答案
您忘记在包含 realloc()
*s 分配新值>.
You've forgotten to assign the new value to *s
in the function that contains realloc()
.
void test(void) // Unaltered; still broken!
{
char *c = malloc(strlen("I like coffe") + 1);
strcpy(c, "I like coffe");
char **s = &c;
while (strlen(*s) < 25)
my_function(s);
}
void my_function(char **s) // Fixed one way
{
char *w = *s;
size_t len = strlen(w) + 1; // Define and initialize len
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
w = tmp;
*s = w; // Reassign to `*s`
}
或者,更简单:
void my_function(char **s) // Fixed another way
{
char *w = *s;
size_t len = strlen(w); // Define and initialize len
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
*s = tmp; // Reassign to `*s`
}
赋值给w
只设置局部变量,它是*s
的副本;它不会重置调用代码中的指针.
Assigning to w
only sets the local variable which is a copy of *s
; it does not reset the pointer in the calling code.
请注意,即使进行了此修复,test()
中的循环仍将运行很长时间,因为 c
中的字符串长度没有任何变化.还有另一个问题:你没有将s
的地址传递给my_function()
,所以my_function()
不能修改s
.
Note that even with this fix, the loop in test()
is going to run a long time because nothing changes the length of the string in c
. There's also another problem: you don't pass the address of s
to my_function()
, so my_function()
can't modify s
.
void test(void)
{
char *c = malloc(strlen("I like coffe") + 1);
strcpy(c, "I like coffe");
while (strlen(c) < 25)
{
my_function(&c);
strcat(c, "AZ"); // Grow string — not good in real code
printf("%2zu: <<%s>>\n", strlen(c), c);
}
}
void my_function(char **s)
{
char *w = *s;
size_t len = strlen(w) + 1; // Define and initialize len
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
*s = tmp; // Reassign to `*s`
}
这取消了 test()
中指向 char 的指针.如果这很重要,则需要进行更多思考.
This does away with the pointer to pointer to char in test()
. If that's crucial, there's more thinking to be done.
代码现已测试——你能说猪耳朵"吗?错误材料的复制粘贴使我的测试代码失败.这是检测的工作版本 - valgrind
给它一个干净的健康清单.
Code now tested — can you say "pig's ear"? Copy'n'paste of the wrong material made my test code fail. Here's the instrumented working version — valgrind
gives it a clean bill of health.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void my_function(char **s)
{
char *w = *s;
size_t len = strlen(w) + 1; // Define and initialize len
printf("M1: %p: %2zu: <<%s>>\n", (void *)w, len, w);
char *tmp = realloc(w, len + 2);
if (tmp != NULL)
*s = tmp; // Reassign to `*s`
printf("M2: %p: %2zu: <<%s>>\n", (void *)*s, strlen(*s), *s);
}
static void test(void)
{
char *c = malloc(strlen("I like coffe") + 1);
if (c == 0)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
strcpy(c, "I like coffe");
printf("T1: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c);
while (strlen(c) < 25)
{
my_function(&c);
printf("T2: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c);
if (c == NULL)
{
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
strcat(c, "AZ"); // Grow string — not good in real code
printf("T3: %p: %2zu: <<%s>>\n", (void *)c, strlen(c), c);
}
free(c);
}
int main(void)
{
test();
return 0;
}
这篇关于Realloc 将指针设置为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!