在C中填充struct中的动态数组

时间:2015-12-01 19:07:20

标签: c struct

嗨我想用数据填充一个结构,所以我写了这段代码,但是当我尝试运行它时它会粉碎并关闭我不知道为什么:

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

struct rectangle{
    float length ;
    float width ;
};


void main()
{
   printf("enter the size of both arrays \n");
   int x ;
   scanf("%d",&x);

struct rectangle *r ;
r = (int *) malloc(x*sizeof(int));
int j ;
 for (j = 0 ; j < x ; j++){
    printf("enter rectangle length \n");
    scanf("%d",r[j].length);
    printf("enter rectangle width \n");
    scanf("%d",r[j].width);

   }
   printf("%d \n",max(r,x));


}

但是当我尝试运行它时会崩溃。

2 个答案:

答案 0 :(得分:2)

您正在分配一个int数据数组,但尝试使用它,好像它是rectangle数据的数组一样。两种类型的大小都不一样。

像这样分配你的数组:

struct rectangle* r = malloc(x*sizeof(struct rectangle));

澄清:

sizeof(int) != sizeof(struct rectangle)

同样scanf需要指向您正在扫描的每个变量的指针。 %d是整数的格式说明符,但长度和宽度是浮点数。

使用:

scanf("%f",&r[j].length);
scanf("%f",&r[j].width);

答案 1 :(得分:1)

您的代码中存在许多细微问题,主要与scanf有关,但是,您对malloc的使用不需要包含演员。 malloc将起始地址返回给新分配的内存块。它只是一个地址(不是int地址或float地址,只是一个void类型的地址。分配内存时,养成在不再需要时释放内存的习惯。现在养成的好习惯还有很长的路要走。

将这些部分放在一起,您可以通过以下方式实现代码:

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

struct rectangle {
    float length;
    float width;
};

int main (void)
{
    size_t j = 0, x = 0;
    struct rectangle *r = NULL;

    printf ("\nenter the size of both arrays: ");
    scanf ("%zu", &x);

    r = malloc (x * sizeof *r);
    if (!r) {    /* validate each and every allocation */
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }

    printf ("\nenter rectangle values:\n\n");
    for (j = 0; j < x; j++) 
    {
        printf ("  enter rectangle length [%zu]: ", j);
        scanf ("%f", &r[j].length);
        printf ("  enter rectangle width  [%zu]: ", j);
        scanf ("%f", &r[j].width);

    }
    /* printf ("%d \n", max (r, x)); */

    printf ("\n rectangle  length  width\n");
    for (j = 0; j < x; j++)
        printf ("  r[%2zu]    %6.2f  %6.2f\n", j, r[j].length, r[j].width);

    free (r);   /* free allocated memory */

    return 0;
}

注意:必须验证所有对scanf的调用的返回,以确认格式说明符中指定的类型转换的预期数量确保输入匹配失败均未发生。 (为简洁起见,上面省略了它们)

编译(已启用警告)

gcc -Wall -Wextra -O3 -o bin/struct_dyn struct_dyn.c

使用/输出

$ ./bin/struct_dyn

enter the size of both arrays: 4

enter rectangle values:

  enter rectangle length [0]: 1
  enter rectangle width  [0]: 12
  enter rectangle length [1]: 2
  enter rectangle width  [1]: 6
  enter rectangle length [2]: 3
  enter rectangle width  [2]: 4
  enter rectangle length [3]: 4
  enter rectangle width  [3]: 3

 rectangle  length  width
  r[ 0]      1.00   12.00
  r[ 1]      2.00    6.00
  r[ 2]      3.00    4.00
  r[ 3]      4.00    3.00

内存错误/泄漏检查

在你的动态分配内存的任何代码中,你有2个责任关于任何分配的内存块:(1)总是保留一个指向内存块起始地址的指针,所以,(2)它可以在释放时释放它不再需要了。您必须使用内存错误检查程序,以确保您没有在已分配的内存块之外/之外写入,并确认已释放已分配的所有内存。对于Linux valgrind是正常的选择。有许多微妙的方法来滥用可能导致实际问题的内存块,没有理由不这样做。每个平台都有类似的记忆检查器。它们都很简单易用。只需通过它运行您的程序。

$ valgrind ./bin/struct_dyn
==18380== Memcheck, a memory error detector
==18380== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==18380== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==18380== Command: ./bin/struct_dyn
==18380==

enter the size of both arrays: 4
<snip>
 rectangle  length  width
  r[ 0]      1.00   12.00
  r[ 1]      2.00    6.00
  r[ 2]      3.00    4.00
  r[ 3]      4.00    3.00
==18380==
==18380== HEAP SUMMARY:
==18380==     in use at exit: 0 bytes in 0 blocks
==18380==   total heap usage: 1 allocs, 1 frees, 32 bytes allocated
==18380==
==18380== All heap blocks were freed -- no leaks are possible
==18380==
==18380== For counts of detected and suppressed errors, rerun with: -v
==18380== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

如果您有任何问题,请与我们联系。