【问题标题】:How can I pass a structure's array in the right way to my function?如何以正确的方式将结构的数组传递给我的函数?
【发布时间】:2019-01-04 08:02:15
【问题描述】:

我正在尝试将结构的数组传递给函数,但是当i 变为 1 acces violation 时,它给了我一个错误。 这是我的代码:

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

typedef struct {
  int locuri;
  int putere;
  char marca[50];
  char culoare[50];
  int an_fabricatie;
}automob;

void aloca(automob **autos, int n)
{
   *autos = (automob*)malloc(sizeof(automob)*n);
   if (autos == NULL) {
      exit(1);
   }
}

void read_autos(const char* filename, automob **A, int *n)
{
    FILE *f_in = fopen(filename, "r");
    int i = 0, aux;
    if (f_in == NULL) {
        printf("Nu s-a gasit fisierul!");
        _getch();
        exit(0);
    }
    fscanf(f_in, "%d", n);
    aloca(A, *n);
    while (i < (*n)) {
        fscanf(f_in, "%d", &A[i]->locuri);
        fscanf(f_in, "%d", &A[i]->putere);
        fscanf(f_in, "%s", &A[i]->marca);
        fscanf(f_in, "%s", &A[i]->culoare);
        fscanf(f_in, "%d", &A[i]->an_fabricatie);
        i++;
    }
}

void main()
{
    int n;
    automob *A;
    read_autos("autos.in", &A, &n);
    _getch();
}

我认为指针 A 没有正确分配,但我真的不知道。你有什么想法?因为当我在主函数中编写它时这有效,但如果我在另一个函数(如read_autos)中正确它就不起作用。

【问题讨论】:

  • 你最好检查 fscanf(f_in,"%d",n); 之后的 n 值因为我有点确定问题在那里
  • 在 fscanf 语句中的 &amp; 之后使用方括号。示例:&amp;A[i]-&gt;locuri 应该是 &amp;(A[i]-&gt;locuri)
  • 我检查了 n 并且没问题,它得到了正确的值。而且我也放了括号,但仍然不起作用。访问违反写入位置0xCCCCCCCC
  • 它确实适用于 A[0],但是当它进入 A[1] 时,它给了我错误
  • 附带说明,请不要使用void main()

标签: c function pointers struct


【解决方案1】:

A[i] -&gt; locuri 表示(* A[i]).locuri;如果A 是指向automob 的指针数组,这将是有意义的;但事实并非如此。你想要(* A)[i].locuri。其他字段依此类推。

    fscanf(f_in, "%d", &(* A)[i].locuri);
    fscanf(f_in, "%d", &(* A)[i].putere);
    fscanf(f_in, "%s", (* A)[i].marca);
    fscanf(f_in, "%s", (* A)[i].culoare);
    fscanf(f_in, "%d", &(* A)[i].an_fabricatie);

你写的:

+------+     +-------+     +--------------------------------------------+
|  A  -----> | A[0] -----> | locuri | putere | marca | culoare | an_fab |
+------+     |       |     +--------------------------------------------+
             +-------+     +--------------------------------------------+
             | A[1] -----> | locuri | putere | marca | culoare | an_fab |
             |       |     +--------------------------------------------+
             +-------+     +--------------------------------------------+
             | A[2] -----> | locuri | putere | marca | culoare | an_fab |
             |       |     +--------------------------------------------+
             +-------+     +--------------------------------------------+
             | A[3] -----> | locuri | putere | marca | culoare | an_fab |
             |       |     +--------------------------------------------+
             +-------+

你想要什么:

+------+     +-------+         +--------------------------------------------+
|  A  -----> | * A  -----> [0] | locuri | putere | marca | culoare | an_fab |
+------+     +-------+         +--------------------------------------------+
                           [1] | locuri | putere | marca | culoare | an_fab |
                               +--------------------------------------------+
                           [2] | locuri | putere | marca | culoare | an_fab |
                               +--------------------------------------------+
                           [3] | locuri | putere | marca | culoare | an_fab |
                               +--------------------------------------------+

【讨论】:

  • 好的,现在我的堆栈周围 A 已损坏,堆栈周围 n 已损坏
  • 使用时,pointers-to-pointers-to-ad nauseum 很容易混淆,并且在取消引用方面会出现错误-深度。像我这样的新手,通常会以过早或过深的方式取消引用一级。这是一个为时过早的案例。不是An 元素,而是*A
  • 好的,现在我可以在结构成员中写入变量 A 周围的堆栈已损坏
  • void aloca(automob *autos, int n) { *autos = (automob)malloc(sizeof(automob)); for (int i = 0; i
  • 试图分配这样的东西
【解决方案2】:

(这是一条评论,但我没有 50 名声望,所以我回答,您可以将其转换为评论)

当我遇到这样的问题并且它发生时,我会毫不犹豫地简单地打印指针值。
例如,在您的情况下:

printf("sizeof %I64u\n",sizeof(automob));
printf("Global Addr %I64u\n",*A);
printf("1st elt Addr %I64u\n",&(*A)[0]);
printf("2nd elt Addr %I64u\n",&(*A)[1]);
printf("1st elt / 1st field Addr %I64u\n",&(*A)[0].locuri);
printf("2nd elt / 2nd field Addr %I64u\n",&(*A)[1].locuri);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    相关资源
    最近更新 更多