-1

In one of the programs, I created a function whose one argument was a pointer. The function dynamically allocated some memory to the pointer and returned the size of allocated memory along with other details. But, the allocated memory is destroyed as soon as the function is executed.

How can I retain access and data integrity outside the function to the memory allocated inside the function?

Here's the code modified after reading the replies:

void initialize(int **arr)
{
  int i = 0;
  *arr = malloc(sizeof(int) * 10);

  for (; i < 10; ++i)
    *arr[i] = i + 1;

  for (i = 0; i < 10; ++i)
    printf("\n%d", *arr[i]);

}

int main()
{

  int i = 0;
  int *arr;
  initialize(&arr);

  for (; i < 10; ++i)
    printf("\n%d", arr[i]);

  return 0;
}

But when I run it, it says "rr.exe has stopped working"; although it compiles successfully. Nothing gets printed, not even from the printf in the the function.

alk
  • 69,737
  • 10
  • 105
  • 255
Harshil Sharma
  • 2,016
  • 1
  • 29
  • 54
  • let's see your code; it would make the answer easier to provide. – verbose Sep 03 '13 at 07:31
  • Change `*arr[i]` to be `(*arr)[i]`. `[]` binds tighter then `*`. – alk Sep 03 '13 at 08:53
  • @alk; did that, now it prints "1" and then the same "rr.exe has stopped working" occurs. – Harshil Sharma Sep 03 '13 at 09:16
  • 1
    Try tracing the code using a debugger. This way you at least find out the line of code where the program stops. – alk Sep 03 '13 at 09:19
  • 1
    You did apply the `()` to both occurrencies of `*arr[i]`, didn't you? – alk Sep 03 '13 at 09:22
  • @alk; got it working. BTW can you explain the difference between *arr[i] and (*arr)[i]> – Harshil Sharma Sep 03 '13 at 09:37
  • You might like to do some research on "operator precedence", on what the `*` operator (dereferencing opertor) does and what the `[]` operator does. The `=` (assignment) operator also seem to be involded. – alk Sep 03 '13 at 09:44
  • @alk: Please enter answers as answers, not comments. – Eric Postpischil Sep 03 '13 at 10:13
  • @EricPostpischil: I honestly try to do so. But: The OP adapted my answer, modifed his/her posting (introducing **new** issues) and commented on his/her own (modified) posting why the adapted modification do not work. What could I do to not mess up the whole thing even more? – alk Sep 03 '13 at 10:16
  • @alk: Either edit your prior answer or delete it and enter a new one. – Eric Postpischil Sep 03 '13 at 10:24

2 Answers2

2

Do not call free() on the pointer received by the dynamical allocation, but return it from the function to the calling process.

Example:

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

/* give_me_memory(void ** ppv, size_t n) allocates n bytes to *ppv. */
/* The function returns 0 on success or -1 on error. On error errno is set accordingly. */
int give_me_memory(void ** ppv, size_t n)
{
  if (NULL == ppv)
  {
    errno = EINVAL; /* Bad input detected. */
    return -1;
  }

  *ppv = malloc(n);
  if (NULL == *ppv)
  {
    return -1; /* malloc() failed. */
  }

  return 0; /* Getting here mean: success */
}

int main(void)
{
  void * pv = NULL;
  if (-1 == give_me_memory(&pv, 42))
  {
    perror("give_me_memory() failed");
    return 1;
  }

  /* Do something with the 42 bytes of memory. */

  free(pv);

  return 0;
}
alk
  • 69,737
  • 10
  • 105
  • 255
  • 1
    it is `char**` to `void**` which isn't much nicer. At that point in `main` there is no apparent reason not to declare `pc` as `void*`, so then no conversion would be necessary. – Jens Gustedt Sep 03 '13 at 08:21
  • (Re-commenting to fix typo): Converting `char * *` to `void * *` is not very nice. There is no guarantee that `void * *` is a general representation of "pointer to any kind of pointer". – unwind Sep 03 '13 at 08:23
1

I guess your function looks like:

void f(int *pointer)
{
    pointer = (int*)malloc(sizeof(int));
}

this is bad because, your function gets a copy of pointer. Imagine your function takes int as argument and changes its value. Original variable passed to function won't changed, because you passed it as a copy. Here We have the same - you can modify what's poitner pointing at, but not pointer itself.

What do we do when we want to pass variable to function so it can be changed inside? We pass it as a pointer. here You need to do the same - pass pointer to pointer:

void f(int **pointer)
{
    *pointer = (int*)malloc(sizeof(int));
}

and call it like this:

int *p = 0;
f(&p);
Michał Walenciak
  • 4,257
  • 4
  • 33
  • 61