理解结构和malloc中的指针

时间:2013-05-14 05:27:21

标签: c pointers struct malloc

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

我写了下面的小程序来玩,但我不确定它是否正常。在一个Linux系统上编译,带有-Wall标志的gcc编译时没有任何问题,但我不确定这是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

亲切的问候,

3 个答案:

答案 0 :(得分: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编程memory managementgarbage collection。也许考虑使用Boehm's conservative GC

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

  

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

咦? “改变指针的分配大小”是什么意思?目前你的代码所做的就是通过为指针分配不同的地址来泄漏你malloc()的20个字节。