带指针的C struct认为我没有正确分配内存

时间:2012-08-05 01:52:54

标签: c unix structure

  typedef struct Data* DATAS;

  struct Data {
      char *name;
      char *city;
      DATAS next;
  };
  typedef struct Data DATA;

  int main(void){
     DATAS tmp;

     tmp=(DATAS) malloc(sizeof(DATA));   
     printf("please enter name:\n");
     scanf("%s",&tmp->name);
     printf("%s\n",&tmp->name);
     printf("please enter city:\n");
     scanf("%s",&tmp->city);
     printf("%s\n",&tmp->name);
     printf("%s\n",&tmp->city);

  return 0;
  }

这是家庭作业的一部分。或者说概念是。我需要使用'typedef struct Data * DATAS;'这让我失望了。当我运行这个时,我用城市的一部分覆盖了名字,所以我得到了这个结果。

please enter name:
name
name
please enter city:
city
namecity
city

任何帮助都会很棒。谢谢。我已尝试使用

的不同malloc变体
tmp=(DATAS) malloc(sizeof(DATA));
tmp=(DATA) malloc(sizeof(DATA));

3 个答案:

答案 0 :(得分:4)

分配struct Data的最佳方式是:

struct Data *tmp;
tmp = malloc(sizeof *tmp);
if (tmp == NULL) {
    /* malloc failed, abort or take corrective action */
}

不建议为指针类型定义typedef(至少我是这样);使用struct Data *明确地使读者更清楚你正在处理指针。

为结构类型定义typedef也是不必要的。 typedef只是为现有类型声明一个新名称;你的类型已经有一个非常好的名字,struct Data。不可否认,您必须重复输入struct关键字,但这不是真正的问题。

投放malloc的结果是不必要的; malloc返回void*结果,可以隐式转换为指针类型。演员表可以隐藏错误,例如忘记所需的#include <stdlib.h>

但这些都是风格问题。您当前的代码:

tmp=(DATAS) malloc(sizeof(DATA));

没问题,应该可以。问题出现在您的代码中。

具有scanf格式的

"%s"需要char* argument. You're giving it the *address* of a char *对象,即类型为char**的值。编译器不一定会警告你。所以这个:

scanf("%s",&tmp->name);

应该是:

scanf("%s", tmp->name);

但这仍然是一个问题,因为tmp->name是一个未初始化的指针。它可能指向内存中的某个随机位置,并且调用尝试在该位置存储数据。或者它可能包含无效地址,导致崩溃。行为未定义。

您需要分配空格来保存名称,并使tmp->name指向它。您可能需要在此处进行另一次malloc()来电。

那么你需要分配多少空间?嗯,没有好的答案,因为scanf("%s", ...)对它将读取的字节数没有限制。无论分配的空间多大,如果输入足够的数据,都可以溢出它。

你可能还不需要担心;请记住未来。现在,您可以分配“足够”的空间(例如,100个字节),并注意不要输入太多数据。这应该足以让您的程序正常运行。 (查看scanf的文档,并考虑使用"100s"之类的内容。)

请记住scanf("%s", ...")读取以空格分隔的输入字符串;如果你输入“John Doe”,它只会读取“John”,留下“Doe”进行下一次输入操作。

(我希望这不是太压倒性的。)

答案 1 :(得分:2)

您正在将未初始化的指针传递给scanf,它使用它们来执行写操作;这是未定义的行为。您还将字符串指针的地址传递给scanfprintf; C中的字符串已经是指针,你不应该将指针传递给I / O例程。

如果您知道名称/城市名称中的字符数限制,您可以阅读如下字符串:

char buf[128]; // 127 is the limit; buffer needs an extra character
printf("please enter name:\n");
scanf("%127s", buf);
size_t len = strlen(buf)+1; // plus one for null terminator
tmp->name = malloc(len);
strcpy(tmp->name, buf);
printf("%s\n", tmp->name); // No ampersand

答案 2 :(得分:0)

您已为包含三个指针的结构分配了空间。您还需要为两个字符串分配空间。您还应确保next字段已正确初始化 - 可能为NULL。

就个人而言,我不打扰DATAS typedef,最好保留宏的所有大写名称(尽管FILE *类型)。