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 . . .
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.
Comments