0

Expanding array dynamicly after user enter string in function dynamic_array My Problem seems to be when i try to use the extended array agian in main after i dynamic_array returns true.

After function call i try to print input with printf("main string: %s\n", input) the program will crash. It seems like the *input in main never gets extended.

int dynamic_array(char *input, int *string_current_len){
  int string_len = 0;
  char temp_c;

  input = (char *) malloc(sizeof(char));

  if(input == NULL) {
    printf("Could not allocate memory!");
    exit(1);
  }  

  printf("File to search in: ");

  while((temp_c = getchar()) != '\n') {
    realloc(input, (sizeof(char)));
    input[string_len++] = temp_c;
  }

  input[string_len] = '\0';

  printf("\nYou entered the string: %s\n", input);
  printf("length of string is %d.\n", string_len);


  *string_current_len = string_len;
  return 1;
}


int main(void) {
  int string_len = 0;
  char *input;

  printf("enter #q as filename or word to quit.\n");
      if(!dynamic_array(input, &string_len)){
       return 0;
      }

   printf("main string: %s\n", input);
   return 0;
}
8
  • Did you read the documentation of every function you are using, e.g. malloc(3), printf(3), ... Commented Oct 1, 2014 at 11:22
  • Yeah i read about that it can be expensive, i want to understand it completely before taking actaully resource use into count. Commented Oct 1, 2014 at 11:35
  • 1
    First try to write a correct program. Later consider optimizing it. Commented Oct 1, 2014 at 11:37
  • If i could write a correct program i would´t be asking, would i? Commented Oct 1, 2014 at 11:39
  • 1
    I mean that you should not care about malloc being expansive. But you should think hard about the size requested to malloc and you should usually initialize or clear the freshly allocated memory zone just after the malloc. Don't forget that malloc can fail, so test that case too. Commented Oct 1, 2014 at 11:44

5 Answers 5

6

This:

realloc(input, (sizeof(char)));

is wrong. The realloc() function doesn't modify the given pointer (it can't!), it returns the new pointer. It can also fail, and return NULL.

Also, the second argument doesn't make any sense at all, it should be the new desired total size of the previously allocated buffer, but you're always passing (a very obscure) 1. It's not "grow this by this amount", it's the rather more low-level "attempt to grow this to this new size, and return the new location of the grown buffer".

Please read the documentation very carefully.

Sign up to request clarification or add additional context in comments.

2 Comments

So realloc will return with a new pointer of input with the number of string_len +1 of type char?
@Nicco Please read the documentation. It will return with a newly allocated buffer of the requested length, which begins with the data that was in the original buffer, or NULL on failure. It's also possible that it returns the same pointer value, if it managed to grow the allocation in place.
0
realloc(input, (sizeof(char)));

You are reallocating with same size (i.e 1 byte). It shoud be:

while((temp_c = getchar()) != '\n') {
    realloc(input, (string_len + 1) * (sizeof(char)));
    input[string_len++] = temp_c;

2 Comments

if this suggestion is used, then the line: input[string_len] = '\0'; will fail because it will be writing past the end of the allocated buffer.
Yes i agree. The fix would be to add realloc(input, (string_len + 1) * (sizeof(char))); before input[string_len] = '\0'; line.
0
if(!dynamic_array(input, &string_len)){
return 0;
}

"input" variable is used without initialization.

realloc(input, (sizeof(char)));

Above "realloc" is returning bad pointer. It may be totally bogus, or it may have been allocated from another heap. The pointer MUST come from the 'local' heap.

1 Comment

True. And the value is not used in the function at all. But that should be rather a comment than an answer.
0

C has a call-by-value semantics. So any changes to formal input inside dynamic_array is not propagated to the caller (e.g. your main).

Your main does not initialize input. If you compiled with all warnings and debug info (as you should), e.g. with gcc -Wall -g, you'll get a warning about that.

I actually recommend to initialize every local variable. This makes the debugging easier (since runs are more reproductible). Useless initializations will be removed by the optimizer.

You could initialize input inside your main with

  char* input = NULL;

and you should redesign your program, perhaps by having a grow_array function (instead of your dynamic_array) which you would call in your main like

 grow_array (&input, &string_len);

I leave up to you to declare and implement grow_array correctly. I'm too lame to do your homework.

Inside your grow_array you want to call malloc and test it:

*pptr = malloc(newsize);
if (!*pptr) { perror ("malloc"); exit (EXIT_FAILURE); };

Don't forget to use the debugger (gdb) to run your program step by step.

I don't recommend using realloc because error handling could be tricky. I would suggest using malloc and free and cleverly copying the data using mempcy.

Read the documentation of every function that you are using, e.g. malloc(3), printf(3)

Comments

0

couple of things that I noticed.

int dynamic_array(char *input, int *string_current_len) should change to 
int dynamic_array(char **input, int *string_current_len)

since this function is trying to modify a pointer. also the call to the function here

 if(!dynamic_array(input, &string_len)){
       return 0;
      }

needs to be:

if(!dynamic_array(&input, &string_len)){
       return 0;
      }

Comments

Your Answer

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.