Having trouble with the array address in C?

Stack

I create a dynamic array name listProduct, now I want to read data from file and insert to this array. But I have some trouble with parse array to function, I know I parse wrong address :( but I can not solve this problem. Some one can help me(I spent 3 hours on it, but it didn't work).Thanks for all

in main()

int main(int argc, char** argv) {

    struct Product* listProduct = (struct Product*) malloc(sizeof(struct Product) * 1); 
    printf("address of listProduct in main: %d \n", &listProduct);
    int length = 0;
    char fileName[] = "products.txt";
    length = readDataFromFile(&listProduct,length,fileName);    
    
    printf("address of listProduct in main after insert \n: %d \n", &listProduct);
    printf("length in main %d \n", length);
    printf("start for in main \n");
    int i;
    for(i =0; i < length; i++){
        printf("%s \n", listProduct[i].tenSanPham);
    }
        
    printf("end for in main \n");   
    return 0;
}

in readFile function

int readDataFromFile(struct Product* listProduct,int length, char fileName[]){
    printf("address of listProduct in readData: %d \n", (*listProduct));
    FILE *fp;
   char buff[1024];
    struct Product product;
   fp = fopen(fileName, "r");

   while(fgets(buff, 255, (FILE*)fp) != NULL){
        product = convertStringToProduct(buff);
        printf("IN readData: %s \n", product.tenSanPham);
        insertProduct(product, &(*listProduct), length);
        length++;
   }
    fclose(fp); 
   int i ;
   printf("\n\ncheck value in listProduct after insert\n");
   for(i = 0; i < length; i++){
    printf("IN FOREACH readData: %s \n", listProduct[i].tenSanPham);
   }  
    printf("read done \n");
    return length;
}

in insert function

void insertProduct(struct Product product, struct Product** listProduct, int length)
{
    printf("addres of listProduct in insert %d \n", (*listProduct));
    printf("Product In Insert: %s \n", product.tenSanPham);
  *listProduct = (struct Product*) realloc(listProduct, sizeof(struct Product) * (length+1));
  (*listProduct)[length] = product;
  printf("Get product inserted: %s length: %d \n", (*listProduct)[length].tenSanPham, length);
  printf("insert done!\n");
}

console:

address of listProduct in main: 6487568
address of listProduct in readData: 6486368
IN readData: FOOD 1
addres of listProduct in insert 1905632
Product In Insert: FOOD 1

--------------------------------
Process exited after 0.5239 seconds with return value 3221226356
Press any key to continue . . .
ikegami

You have numerous errors. A number of them would be found by enabling your compilers warnings. Use -Wall -Wextra -pedantic (gcc/clang) or your compiler's equivalent when compiling.

First of all, realloc(listProduct, ...) should be realloc(*listProduct, ...).

Secondly, realloc can return a different address than it was provided. That's why insertProduct takes a struct Product**. This allows it to change the caller's pointer. readDataFromFile needs to do the same thing. The argument needs to be a struct Product **. The fact that the address changes is not a problem.

This will incidentally fix a number of errors you currently have. For example, &(*listProduct) will become correct. However, it's better written as listProduct.

After making the above fixes, listProduct[i].tenSanPham will need to be changed to (*listProduct)[i].tenSanPham.

%p is used for pointers, not %d. And they (weirdly) need to be cast to void* for %p.

You don't check if realloc and fopen succeed.

Fixed:

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

struct Product { ... };

typedef struct Product Product;  // So we don't have to use "struct Product" everywhere.

Product convertStringToProduct(const char *s) {
    ...
}

void insertProduct(Product **listProductPtr, size_t *lengthPtr, Product product) {
    printf("[insertProduct] Address of variable in caller: %p\n", (void*)listProductPtr);
    if (*lengthPtr)
        printf("[insertProduct] Address of first product: %p\n", (void*)*listProductPtr);  // Same: &((*listProduct)[0])

    Product *tmp = realloc(*listProductPtr, sizeof(Product) * (*lengthPtr + 1));
    if (!tmp) {
       // ...
    }

    *listProductPtr = tmp;
    (*listProductPtr)[(*lengthPtr)++] = product;

    printf("[insertProduct] Address of variable in caller: %p\n", (void*)listProductPtr);
    if (*lengthPtr)
        printf("[insertProduct] Address of first product: %p\n", (void*)*listProductPtr);  // Same: &((*listProduct)[0])
}

void readDataFromFile(Product **listProductPtr, size_t *lengthPtr, const char *fileName) {
    printf("[readDataFromFile] Address of variable in caller: %p\n", (void*)listProductPtr);
    if (*lengthPtr)
        printf("[readDataFromFile] Address of first product: %p\n", (void*)*listProductPtr);  // Same: &((*listProduct)[0])

    FILE *fp = fopen(fileName, "r");
    if (!fp) {
       // ...
    }

    char buff[1024];
    while (fgets(buff, sizeof(buf), fp)) {
        Product product = convertStringToProduct(buff);
        insertProduct(listProductPtr, lengthPtr, product);
    }

    fclose(fp); 

    printf("[readDataFromFile] Address of variable in caller: %p\n", (void*)listProductPtr);
    if (*lengthPtr)
        printf("[readDataFromFile] Address of first product: %p\n", (void*)*listProductPtr);  // Same: &((*listProduct)[0])
}

int main(void) {
    Product *listProduct = NULL;
    size_t length = 0;

    printf("[main] Address of listProduct variable: %p\n", (void*)&listProduct);
    if (length)
        printf("[main] Address of first product: %p\n", (void*)listProduct);  // Same: &(listProduct[0])

    readDataFromFile(&listProduct, &length, "products.txt");
    
    printf("[main] Address of listProduct variable: %p\n", (void*)&listProduct);
    if (length)
        printf("[main] Address of first product: %p\n", (void*)listProduct);

    for (size_t i=0; i<length; ++i) {
        printf("%s\n", listProduct[i].tenSanPham);
    }
        
    return 0;
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

TOP Ranking

HotTag

Archive