0

I want to create a function, where I will scann elements (int) to an array and call this fuction in main, freeing memory also has to be in main.

int main () {
 int size = 0;
 int* arr = malloc (sizeof(int));
 char sign;
 int i = 0;
 do {
 scanf ("%d%c", &arr[i], &sign);
 i++;
 arr = realloc(arr, sizeof(int) * (i + 1));
 } while (sign != '\n');
 free(arr);
}

I 've tried to do this,

void initialize(int* arr) {
 char sign;
 int i = 0;
 do {
 scanf ("%d%c", &arr[i], &sign);
 i++;
 arr = realloc(arr, sizeof(int) * (i + 1));
 } while (sign != '\n');
}
int main () {
 int size = 0;
 int* arr = malloc (sizeof(int));
 
 initialize(arr); 
 free(arr);
 }

but I have an error

==140978== 1 errors in context 1 of 2:
==140978== Invalid free() / delete / delete[] / realloc()
==140978== at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==140978== by 0x1092A0: main (lol.c:21)
==140978== Address 0x4a9a040 is 0 bytes inside a block of size 4 free'd
==140978== at 0x484DCD3: realloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==140978== by 0x109244: initialize (lol.c:10)
==140978== by 0x109294: main (lol.c:19)
==140978== Block was alloc'd at
==140978== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==140978== by 0x109284: main (lol.c:17)

Can I scann and fill a dynamic array in this way?

asked Jul 9, 2022 at 15:42

3 Answers 3

2
  1. You need to pass pointer to pointer.
  2. It is better to return size instead of relying on the sentinel values.
  3. Readin input is not good. It will not work. A single read will terminate the loop.
  4. Check the return value of scanf
  5. Check the return value of realloc
  6. Use objects not types in sizeof's
size_t initialize(int **arr) 
{
 size_t i = 0;
 int number;
 char line[100];
 while(fgets(line, sizeof(line), stdin) != NULL) 
 {
 if(sscanf(line, "%d", &number) == 1)
 {
 int *tmp;
 i++;
 tmp = realloc(*arr, sizeof(**arr) * i);
 if(tmp) 
 {
 *arr = tmp;
 (*arr)[i - 1] = number;
 }
 else 
 {
 /* error handling */
 }
 }
 else break;
 }
 return i;
}
int main (void) 
{
 size_t size;
 int *arr = NULL;
 
 size = initialize(&arr); 
 for(size_t i = 0; i < size; i++) printf("arr[%zu] = %d\n", i, arr[i]);
 free(arr);
}

https://godbolt.org/z/6zT47Kdxh

answered Jul 9, 2022 at 16:09
Sign up to request clarification or add additional context in comments.

2 Comments

Nice use of sizeof(object).
Thank you for your answer, but what is line[100] and will it be a problem, if my string will contain up to 10000 symbols, for example?
0

Return the new pointer like realloc does it.

int* initialize(int* arr) {
 char sign;
 int i = 0;
 do {
 scanf ("%d%c", &arr[i], &sign);
 i++;
 arr = realloc(arr, sizeof(int) * (i + 1));
 } while (sign != '\n');
 return arr;
}
int main () {
 int size = 0;
 int* arr = malloc (sizeof(int));
 
 arr = initialize(arr); 
 free(arr);
 }

realloc is able to work with NULL. You can improve your code.

int* initialize(int* arr) {
 char sign;
 int i = 0;
 do {
 arr = realloc(arr, sizeof(int) * (i + 1));
 scanf ("%d%c", &arr[i], &sign);
 i++;
 } while (sign != '\n');
 return arr;
}
int main () {
 int size = 0;
 int* arr = initialize(NULL); 
 free(arr);
 }
answered Jul 9, 2022 at 16:02

8 Comments

Print entered values in main. Do you know how many numbers have been entered?
It seems you wanted to ask OP about this.
reading is invalid too. godbolt.org/z/afoGxPzfx guess why it does not read the numbers. DV-ted as you do posted code which does not work
No, I wanted to ask you.
Neither me want it, nor OP wants to print values. OP wants free.
|
0

When passing a pointer to a function and invoking realloc on it, you are freeing the memory that the pointer points to. So after the initialize function finishes its execution, you are calling free on an invalid pointer (it was already freed). What you should probably do is manipulating with a double pointer:

void initialize(int** arr) {
 char sign;
 int i = 0;
 do {
 scanf ("%d%c", &(*arr)[i], &sign);
 i++;
 *arr = realloc(*arr, sizeof(int) * (i + 1));
 } while (sign != '\n');
}

And invoking this function would look like this:

initialize(&arr);

This way you are writing the newly allocated address with realloc by unreferencing the pointer, so that after initialize function exits you will see the reallocated address.

Also it is also a good practice to check the value of a pointer after calling malloc and realloc. See proper usage of realloc

answered Jul 9, 2022 at 16:08

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.