如果我做任务但是在malloc之后没有memcpy会有什么后果吗?

时间:2013-05-19 20:15:49

标签: c malloc memcpy

在以下程序中:

int main()
{
  struct Node node;
  struct Node* p = (Struct Node*) malloc(sizeof(struct Node));
  *p =node;
  printf("%d\n", *p->seq);
}

通常我做memcpy(p, node, sizeof(node))

现在我尝试了上面的代码,它运行正常,如果我做了作业,我担心会有任何后果或错误的内容,但memcpy之后不会malloc。 有没有或任务是非常正确的? 谢谢!

5 个答案:

答案 0 :(得分:6)

耶稣拉莫斯是对的:

1)*p =node;复制" node"中的所有内容到" * p"

2)你需要一个无关的" memcpy()"

3)你必须分配" * p" (在执行复制之前使用" malloc()")。

这是一个独立的测试:

// C source
#include <stdio.h>
#include <malloc.h>

struct Node {
    int a;
    int b;
    struct Node *next;
};

int
main() {
  struct Node node;
  struct Node *p = malloc(sizeof(struct Node));
  *p = node;
  return 0;
}


# Resulting assembler
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $20, %esp
        movl    $12, (%esp)
        call    malloc
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %edx
        movl    -20(%ebp), %eax
        movl    %eax, (%edx)
        movl    -16(%ebp), %eax
        movl    %eax, 4(%edx)
        movl    -12(%ebp), %eax
        movl    %eax, 8(%edx)
        movl    $0, %eax
        addl    $20, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret

答案 1 :(得分:4)

直接分配应该没问题。实际上,实现可以通过memcpy实现它。摘自ISO C99规范第6.2.6.1节的脚注42:

  因此,例如,结构分配可以一次一个地实现或者通过   memcpy

使用memcpy和分配struct之间的唯一区别是赋值(如果实现为一次元素)将不会保留任何填充位中存储的值到{ {1}}。但是,这只会在您碰巧关心这些位存储的不常见情况下才会起作用(例如,如果您打算在struct之后使用memcmp)。

答案 2 :(得分:3)

这样可以很好地为你复制。

答案 3 :(得分:2)

除非你遗漏了一些代码,否则这项任务毫无意义。

struct Node node; // uninitialized variable
struct Node *p = malloc(sizeof(struct Node));
*p = node; // copy an uninitialized variable to a new place

想象一下,你是一名秘书,而你的老板会给你指示:

  1. 从回收箱中取出一些纸张。

  2. 从回收箱中取出第二张纸。

  3. 将第一张纸的内容复制到第二张纸上。

  4. 没有任何意义。注意memcpy()本质上等同于此处的赋值。 memcpy()和赋值都没有意义,因为node未初始化。

答案 4 :(得分:0)

忽略您正在复制未初始化的值的事实,我认为您在分配时遇到了错误的结束。

分配意味着使用赋值运算符执行。作业是语言的核心部分,因此设计师提供了一流的操作员来执行它。使用该运算符=来执行赋值。

在许多情况下,您可以使用memcpy执行作业,但为什么要这样做?它更冗长,对读者来说完全不透明。你永远不会取代

i = 42;

调用memcpy。

底线,使用=赋值运算符执行赋值。