【问题标题】:How do I modify a char** in another function如何在另一个函数中修改 char**
【发布时间】:2023-01-11 01:14:50
【问题描述】:

这是我期望我的字符串数组在程序运行后的样子:{"#0", "#1", "2"}。
这就是我得到的:{"#2", "#2", "2"}。
如何修改这段代码,以便在函数执行后可以在 main 中获取 {"#0", "#1", "#2"}? 我究竟做错了什么?请帮忙。

#include <stdio.h>

void func(char **s){
    for(int i=0; i<3; i++){
        char buf[10];
        snprintf(buf, 10, "#%d",i);
        s[i]=buf;
    }
}
int main()
{
    char *s[3];
    func(s);
    for(int i=0; i<3; i++){
        printf("%s", s[i]);
    }
    return 0;
}

【问题讨论】:

  • 请学习使用纯 C++ 编码,而不是 C 中的类似代码。您的代码具有未定义的行为,因为它返回一个指向局部变量的指针,该变量的生命周期结束。
  • 你的错误是s[i]=buf; 请记住 buf 是 for 循环内范围的局部变量。一旦你点击} buf 变量并且它的内容不再存在但是你正在复制指针而不是指针指向的内容所以你将指针保存到不存在的对象。
  • 有几种不同的方法可以做到这一点,如果不进一步了解您的家庭作业或课堂作业,就不可能告诉您确切的方法。显然,您应该以特定方式执行此操作,无论是通过动态分配、预分配缓冲区还是其他方式。您的 C++ 教科书或布置此练习题的 C++ 课程的章节主题是什么?不用说,如果您没有以预期的方式执行此操作,您将不会因您的解决方案而受到赞誉。
  • 那么你正在学习C而不是C++。手动内存管理应该是一个高级主题,需要有理由才能使用。
  • @Unyaya { char buf[10]; ... } - 在}你松了buf。它已经不复存在了。您在 buf 上指向的任何内容现在都是一个“悬挂”指针,并从那些悬挂指针指向的内存中读取未定义的行为.

标签: c double-pointer char-pointer


【解决方案1】:

给定两个指针 pq,语句:

p = q;

不会将q指向的内存内容复制到p指向的内存内容。它复制指针值,这样 pq 现在都指向同一内存,并且在使用 q 时反映通过 p 对内存的任何更改。

话虽这么说,声明:

char buf[10];

buf 声明为 10 个 chars 的数组。它的生命周期与其定义块的执行相对应。一旦函数返回,它就会被销毁,s 现在是不确定的。不确定的指针会导致未定义的行为。

【讨论】:

  • 你知道我如何复制指针的内容并将其添加到我原来的指针吗?
  • 您可以使用 s[i] = new[strlen(buf)] 分配一个新缓冲区并使用 strcpy 或使用 strdup。对于 strdup() 你可以做 s[i] = strdup(buf); 因为 strdup() 使用 malloc 为你分配一个缓冲区:https://en.cppreference.com/w/c/experimental/dynamic/strdup
  • 当我执行 *s[i]=*buf 时,我的 printf 什么也不输出。
  • s[i] 指向什么?答案是什么。您需要在复制之前先分配 s[i] 。
  • 标准提供了一个函数 strcpy 来复制两个字符串。还有另一个函数strdup 复制一个字符串并返回复制的字符串。
【解决方案2】:

首先,数组中的每个元素都指向同一个字符数组。

其次,他们都指向一个当地的字符数组。这会导致未定义的行为。

函数中的局部变量在堆栈上分配。当函数调用结束时,那段内存可能被其他值覆盖。

【讨论】:

  • 你知道我如何改变它以便我可以使用局部变量来改变我的指针吗?
  • 你不能。 C 不是这样工作的。当执行离开范围时,在函数中声明的局部变量会被销毁,从而为您留下指向已销毁对象的指针。这就是为什么您需要使用解释这些基本 C 概念的优秀教科书来学习 C,而不是尝试编写一些临时代码。为了获得最佳效果,您应该坚持 C 教科书中的课程计划。
  • @SamVarshavchik 我知道每个 *s 都指向同一个局部变量,这就是为什么我为每个元素都得到“#2”的原因,因为这是循环结束时局部变量的值。是否可以取消引用我的指针以使指针本身的值发生变化?例如,如果我写 s[0]="ABC",指针本身的值就会改变。
  • 这就是为什么我要求你解释你希望从这个练习中学到什么具体的编程主题,因为有几种不同的编程方法。 Stackoverflow 是为了具体的编程题。 Stackoverflow 不是 C 教程站点,也不是帮助站点,也不是 C 教科书的替代品。我们只回答具体的问题。您对哪个特定的 C 主题有疑问?
  • @Unyaya 您可以在动态分配的内存中为要返回的每个指针创建本地缓冲区的副本。阅读有关strlenmallocstrcpystrdup 的信息(如果可用)。请注意,字符串的副本需要比从strlen 返回的数字多一个字节。
猜你喜欢
  • 2012-06-05
  • 2012-02-27
  • 2021-11-23
  • 2023-04-06
  • 1970-01-01
  • 2021-09-03
  • 2021-06-14
  • 1970-01-01
  • 2019-10-25
相关资源
最近更新 更多