【问题标题】:Entering the number of elements in malloc function for a dynamic structure array in c在 c 中为动态结构数组输入 malloc 函数中的元素数
【发布时间】:2012-12-27 15:39:14
【问题描述】:


目前,我尝试理解 C 中的动态数组。 当我为指针“ptr”分配内存时,它可以在不输入我需要的元素数量(在 malloc 函数中)的情况下工作。
现在,问题是,不明白它为什么起作用。
如果有人能给我一些建议,那就太好了。 谢谢。

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

struct daten
{
    char name[20];
    int alter;
};

int main(void)
{
    struct daten *ptr;
    int i;

    ptr = malloc(sizeof(struct daten *)); //works fine!!
    //ptr = malloc(sizeof(struct daten *)*4);
    strcpy(ptr[0].name, "Daniel");
    ptr[0].alter = 23;

    strcpy(ptr[1].name, "Fabian");
    ptr[1].alter = 29;

    strcpy(ptr[2].name, "Helmut");
    ptr[2].alter = 34;

    strcpy(ptr[3].name, "Katrin");
    ptr[3].alter = 21;

    for(i = 0; i<4; i++)
    {
        printf("%s\t", ptr[i].name);
        printf("%d\n", ptr[i].alter);

    }

    return 0;
}

【问题讨论】:

  • 请更改sizeof(struct daten *) -> sizeof(struct daten)。你想存储一个对象,而不是一个指向对象的指针。
  • @KarthikT 而不是sizeof(*ptr)
  • @H2CO3 啊是的,有点干净。
  • @KarthikT 并不是说​​它更干净,但是当ptr 变为struct daten * 以外的任何内容并且您忘记在malloc() 调用中更改类型时,sizeof(struct daten) 会中断。
  • @H2CO3 是的,我的意思是这样,因为减少了逻辑重复,正如您所指出的那样,更改代码更容易。

标签: c arrays pointers dynamic malloc


【解决方案1】:

这是未定义的行为。你只是(不)幸运的是它的工作。如果你在不同的系统上尝试这个,它可能会也可能不会。

你应该这样做:

ptr = malloc(sizeof(struct daten)*4);

操作成功,因为数据可能在分配空间之后被写入内存。由于这是未分配的空间,因此您没有任何问题,它是working。当您尝试使用此空间时,您也会遇到问题。

【讨论】:

    【解决方案2】:

    ptr[3] 也可以表示为*(ptr + 3),其中“3”缩放为(3 * sizeof(*p))。因此,它会将数据复制到超出您分配的内存的某个内存位置。

    你很幸运,或者我应该说你很不幸。你所做的有点像随意刺伤某人,你可能会击中一个重要器官,也可能不会。这次你没有,编译代码而不调试(例如)来改变内存布局,你可能会遇到一些会杀死进程的东西。或者也许不杀死它,而只是伤害它。

    您已经了解了 C 编程必须遵守纪律的原因之一。不,它没有“工作”,你的测试不足以证明它失败了。

    另见calloc

    【讨论】:

    • ptr + 3ptr + (3 * sizeof(struct daten) 不同。指针算术意味着乘以sizeof (*p)
    • 是的,我试图说它是按比例缩放的。
    【解决方案3】:

    嗯,你只是写到未分配的区域。这可以工作,但从长远来看,您会遇到崩溃,因为您的堆很可能会因写入未分配的区域而损坏,因此连续的 malloc 可能会失败或使您的程序崩溃。

    【讨论】:

      【解决方案4】:

      关键字是它不能“正常工作”。至多它似乎在起作用。

      您在这里拥有的是未定义的行为(因为您正在为一个结构分配空间,但是,您正在写入更大的空间)。未定义的行为可以做任何事情;这并不意味着程序必须崩溃。这包括它可能“正常工作”。

      另外,您误解了应该分配多少内存。对于T 类型,分配给T * 类型的指针,应分配sizeof(T) 字节,如下所示:

      ptr = malloc(sizeof(struct daten) * 4);
      

      更好:

      ptr = malloc(sizeof(*ptr) * 4);
      

      【讨论】:

        【解决方案5】:

        由于这是一种未定义的行为,任何事情都可能发生:您的程序可能运行良好。但这并不意味着它是一个正确的程序。

        因此您必须分配足够的内存来执行此操作,即sizeof(struct daten) * 4 字节。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多