0

我只是在学习 C(在 24 小时内阅读 Sam 的 Teach Yourself C)。我已经完成了指针和内存分配,但现在我想知道它们在一个结构中。

我写了下面的小程序来玩,但我不确定它是否可以。使用 gcc 在 Linux 系统上编译,-Wall编译的标志没有任何问题,但我不确定它是否 100% 值得信赖。

可以像我在下面所做的那样更改指针的分配大小,还是我可能踩到相邻的内存?我在结构中做了一些前后变量来尝试检查这一点,但不知道这是否有效以及结构元素是否连续存储在内存中(我猜是这样,因为指向结构的指针可以传递给一个函数和通过指针位置操作的结构)。另外,如何访问指针位置的内容并对其进行迭代,以便确保如果它是连续的,则不会覆盖任何内容?我想我要问的一件事是如何以这种方式调试内存混乱以知道它不会破坏任何东西?

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

struct hello {
    char *before;
    char *message;
    char *after;
};

int main (){
    struct hello there= {
        "Before",
        "Hello",
        "After",
    };
    printf("%ld\n", strlen(there.message));
    printf("%s\n", there.message);
    printf("%d\n", sizeof(there));
    there.message = malloc(20 * sizeof(char));
    there.message = "Hello, there!";
    printf("%ld\n", strlen(there.message));
    printf("%s\n", there.message);
    printf("%s %s\n", there.before, there.after);
    printf("%d\n", sizeof(there));
    return 0;
}

我在想有些不对劲,因为我的大小there没有改变.kj

亲切的问候,

4

3 回答 3

1

不太好,你有内存泄漏,你可以使用valgrind在运行时检测它(在 Linux 上)。

您正在编码:

there.message = malloc(20 * sizeof(char));
there.message = "Hello, there!";

第一个赋值调用malloc(3)。首先,打电话时malloc你应该总是测试它是否失败。但实际上它通常会成功。所以至少更好的代码:

there.message = malloc(20 * sizeof(char));
if (!there.message) 
  { perror("malloc of 20 failed"); exit (EXIT_FAILURE); }

第二个赋值将常量文字字符串的地址"Hello, there!"放入同一个指针there.message中,你丢失了第一个值。您可能想要复制该常量字符串

strncpy (there.message, "Hello, there!", 20*sizeof(char));

(你可以只使用strcpy(3)但要注意缓冲区溢出)

您可以使用strdup(3)获得一些字符串的新副本(堆中)(并且 GNU libc 也有asprintf(3) ...)

there.message = strdup("Hello, There");
if (!there.message) 
  { perror("strdup failed"); exit (EXIT_FAILURE); };

free最后,在程序结束时堆内存是很好的品味。(但操作系统会在_exit(2)时间抑制进程空间。

阅读有关C 编程内存管理垃圾收集的更多信息。也许考虑使用Boehm 的保守 GC

AC 指针只是一个内存地址区。应用程序需要知道它们的大小。

PS。C 中的手动内存管理很棘手,即使对于经验丰富的资深程序员也是如此。

于 2013-05-14T05:31:33.500 回答
0

there.message = "Hello, there!"不会将字符串复制到缓冲区中。它将指针设置为一个新的(通常是静态的)缓冲区,其中包含字符串“Hello, there!”。因此,编写的代码存在内存泄漏(分配的内存在程序退出之前永远不会被释放)。

但是,是的,malloc 本身就很好。您通常会使用 strncpy、sprintf 或类似函数将内容复制到如此分配的缓冲区中。

于 2013-05-14T05:31:59.307 回答
0

可以更改指针的分配大小 [...] 吗?

嗯?“更改指针的分配大小”是什么意思?目前,您的所有代码所做的都是malloc()通过为指针分配不同的地址来泄漏您吃掉的 20 个字节。

于 2013-05-14T05:32:01.027 回答