如何从c中的动态数组访问数据?

时间:2020-12-14 23:55:03

I've got two different arrays that I'm using. With one, I'm getting the exact results that I want, the other, not so much. I'm filing the arrays with by reading from a text file similar to this:

我有两个不同的数组。有一个,我得到了我想要的结果,另一个,不是那么多。我通过从一个类似这样的文本文件中读取数组:

2597
283



4
723
21
82
426

The first five lines would be the customer IDs. There is always 5 lines but they don't always have a value. The next line is the number of vendors, then followed by the vendor ids.

前五行是客户id。总有5行,但它们并不总是有值。下一行是供应商的数量,然后是供应商id。

void use_arrays()
{
    int
        i,
        customer_count,
        *customer_ids,
        vendor_count,
        *vendor_ids;

    customer_ids = malloc(sizeof(int));
    vendor_ids = malloc(sizeof(int));
    fill_arrays(&customer_count, customer_ids, &vendor_count, vendor_ids);

    for (i = 0; i < customer_count; i++)
    {
        printf("Customer[%d]: %d\n", i, customer_ids[i]);
    }

    for (i = 0; i < vendor_count; i++)
    {
        printf("Vendor[%d]: %d\n", i, vendor_ids[i]);
    }

    free(customer_ids);
    free(vendor_ids);
}

void fill_arrays(int *customer_count, int *customer_ids, int *vendor_count, int *vendor_ids)
{
    int
        i,
        *temp,
        customer_id,
        vendor_id,
        num_cust = 0;
    FILE
        *inp_file;
    char
        *endptr = NULL,
        buffer[500];

    inp_file = fopen(g_filename, "r");

    for (i = 0; i < 5; i++) /* Can't be more than 5 customers */
    {
        fgets(buffer, sizeof(buffer), inp_file);
        customer_id = strtol(buffer, &endptr, 0);
        if (customer_id != 0)
        {
            customer_ids[i] = customer_id;
        temp = realloc(customer_ids, (i+2)*sizeof(int));
        if (temp != NULL) 
            {
               customer_ids = temp;
            } 
        else 
        {
               printf("Couldn't allocate memory\n");
            }
        num_cust++;
        }
    }
    *customer_count = num_cust;

    /* Next is number of vendor ids*/
    fgets(buffer, sizeof(buffer), inp_file);
    *vendor_count = strtol(buffer, &endptr, 0);

    temp = realloc(vendor_ids, *vendor_count*sizeof(int));
    if (temp != NULL) 
    {
        vendor_ids = temp;
    } 
    else 
    {
        printf("Couldn't allocate memory\n");
    }

    for (i = 0; i < *vendor_count; i++)
    {
        fgets(buffer, sizeof(buffer), inp_file);
        vendor_id = strtol(buffer, &endptr, 0);
        if (vendor_id != 0)
        {
        vendor_ids[i] = vendor_id;
        }
    }
    fclose(inp_file);
}

Once the arrays print out, customer_ids is showing the correct numbers but vendor_ids is printing out random numbers from memory. To be more frustrating, it prints the vendors correctly from inside fill_arrays.

一旦数组打印出来,customer_ids将显示正确的数字,但是vendor_ids将从内存中打印随机数。更令人沮丧的是,它从fill_array中正确地打印供应商。

2 个解决方案

#1


4  

If you want to modify vendor_ids the way you do in fill_arrays, then you have to pass it in as a pointer to a pointer:

如果您想在fill_array中修改vendor_ids,那么您必须将其作为指针传递给指针:

fill_arrays(int *customer_count, int *customer_ids, int *vendor_count, int **vendor_ids)

Call it like this:

叫它是这样的:

fill_arrays(&customer_count, customer_ids, &vendor_count, &vendor_ids);

Then you can realloc like so:

那么你可以这样说:

temp = realloc(*vendor_ids, *vendor_count*sizeof(int));
if (temp != NULL) 
{
    *vendor_ids = temp;
} 

Also, at the end of your function:

同时,在你的职能结束时:

vendor_ids[i] = vendor_id;

will have to change to

要换成吗

(*vendor_ids)[i] = vendor_id;

You will also have to make the same changes to customer_ids. The fact that customer_ids was working while vendor_ids wasn't was probably due to your use of realloc. If realloc decides that the memory block has to be reallocated in a new location, you'll run into these problems but if reallocates the memory in the same location, your pointer that you passed in is still pointing there. Since you never know if realloc is going to make that descision or not, both customer_ids and vendor_ids should be passed in as pointers to pointers.

您还必须对customer_id进行相同的更改。customer_ids在vendor_ids不工作的事实可能是由于您使用了realloc。如果realloc决定必须重新分配内存块到一个新的位置,您将遇到这些问题,但是如果重新分配相同位置的内存,您传入的指针仍然指向那里。因为您永远不知道realloc是否会做出那样的决定,所以customer_id和vendor_id都应该作为指针传入。

#2


0  

You seem a bit confused how to return memory from a function.

您似乎有点困惑如何从函数返回内存。

if you have a function that looks like this

如果你有一个像这样的函数

void foo(int a);

空白foo(int);

you can not change a inside of foo, foo only gets a copy of a.

你不能改变foo的内部,foo只能得到a的副本。

void foo(int *a);

空白foo(int *);

otoh gives foo the address of a, i.e. "i know where you live" it lets you change what a points to. if a points to an array then you can change the contents of that array, if a points to a single integer you can change that.

otoh给出了foo a的地址,即。“我知道你住在哪里”它可以让你改变a的指向。如果一个点指向一个数组,那么你可以改变这个数组的内容,如果一个点指向一个整数,你可以改变它。

void foo(int **a);

空白foo(int * *);

lets you change not only what a points to, but also where it points. so if you want a to point to somewhere else you can. this is what you need in your function, if you do a malloc/calloc/realloc in your function to return the result you need this

不仅可以改变a指向什么,还可以改变它指向什么地方。所以如果你想指向其他地方你可以。这是您在函数中需要的,如果您在函数中执行malloc/calloc/realloc来返回您需要的结果

#1


4  

If you want to modify vendor_ids the way you do in fill_arrays, then you have to pass it in as a pointer to a pointer:

如果您想在fill_array中修改vendor_ids,那么您必须将其作为指针传递给指针:

fill_arrays(int *customer_count, int *customer_ids, int *vendor_count, int **vendor_ids)

Call it like this:

叫它是这样的:

fill_arrays(&customer_count, customer_ids, &vendor_count, &vendor_ids);

Then you can realloc like so:

那么你可以这样说:

temp = realloc(*vendor_ids, *vendor_count*sizeof(int));
if (temp != NULL) 
{
    *vendor_ids = temp;
} 

Also, at the end of your function:

同时,在你的职能结束时:

vendor_ids[i] = vendor_id;

will have to change to

要换成吗

(*vendor_ids)[i] = vendor_id;

You will also have to make the same changes to customer_ids. The fact that customer_ids was working while vendor_ids wasn't was probably due to your use of realloc. If realloc decides that the memory block has to be reallocated in a new location, you'll run into these problems but if reallocates the memory in the same location, your pointer that you passed in is still pointing there. Since you never know if realloc is going to make that descision or not, both customer_ids and vendor_ids should be passed in as pointers to pointers.

您还必须对customer_id进行相同的更改。customer_ids在vendor_ids不工作的事实可能是由于您使用了realloc。如果realloc决定必须重新分配内存块到一个新的位置,您将遇到这些问题,但是如果重新分配相同位置的内存,您传入的指针仍然指向那里。因为您永远不知道realloc是否会做出那样的决定,所以customer_id和vendor_id都应该作为指针传入。

#2


0  

You seem a bit confused how to return memory from a function.

您似乎有点困惑如何从函数返回内存。

if you have a function that looks like this

如果你有一个像这样的函数

void foo(int a);

空白foo(int);

you can not change a inside of foo, foo only gets a copy of a.

你不能改变foo的内部,foo只能得到a的副本。

void foo(int *a);

空白foo(int *);

otoh gives foo the address of a, i.e. "i know where you live" it lets you change what a points to. if a points to an array then you can change the contents of that array, if a points to a single integer you can change that.

otoh给出了foo a的地址,即。“我知道你住在哪里”它可以让你改变a的指向。如果一个点指向一个数组,那么你可以改变这个数组的内容,如果一个点指向一个整数,你可以改变它。

void foo(int **a);

空白foo(int * *);

lets you change not only what a points to, but also where it points. so if you want a to point to somewhere else you can. this is what you need in your function, if you do a malloc/calloc/realloc in your function to return the result you need this

不仅可以改变a指向什么,还可以改变它指向什么地方。所以如果你想指向其他地方你可以。这是您在函数中需要的,如果您在函数中执行malloc/calloc/realloc来返回您需要的结果