Realloc 将指针设置为空 [英] Realloc setting pointer to empty

查看:84
本文介绍了Realloc 将指针设置为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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 将指针设置为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆