0

Read:

and other questions on SO related to this question and other on world wide web, so continue reading...

Since soon, i figure, i never alloc like this memory for char *, but I thought it may work:

void _alloc(char *line)
         *line = malloc(sizeof(char) * BUFSIZE);

Ignore error handler in _alloc and main. The main thing is SEGFAULT on section like this:

 main()
   {
       char *text, *start;
       _alloc(text);
       start = text;
       // add contents in text briefly
       *text++ = 'd'; *text = '\0';  // SEGFAULT
       fprintf(stdout, "%s", start);
   }

I had a picture that function _alloc working something like this:

    main()
   {
     char *text;
     /// function _alloc:
     char *tmp = text;
     *tmp  = malloc ( sizeof(char) * BUFSIZE);
     /// end
   }

And... When i tried this, it give me warning: assignment makes integer from pointer without a cast and SEGF. My picture about it , is:

tmp = text; // tmp point at address of line
 *tmp = malloc(...); // tmp change to what point line...

And i saw that i need in _alloc( char **) , and can't figure how it works with **. I tried to manipulate with array[][], i know it. But can't get picture, why it need to be char **? Here is part of answer:

Here, line is a local variable within _alloc . Pointers are passed by value in C, so a receives a copy of the pointer in main when you do _alloc(text); < answer user nos (modified with my name of variables) on Scope of malloc used in a function

P.S. i know that is simpler to write function like this char *_alloc();

Community
  • 1
  • 1
RadijatoR
  • 113
  • 9

2 Answers2

2

Let's take a simple example, with an int.

Suppose we have the functions :

void foo(int n)
{
    n = 3;
}

int main(void)
{
   int number = 5;
   foo(number);
}

I think you will agree that number is not modified after foo(number). This is because n is only a copy of number, a local variable which is destroyed after foo exited.

This is the reason why we use pointers. But a pointer is a variable, and it's exactly the same thing. Look at this example :

void bar(int *n)
{
   *n = 3;
   int *temp = malloc(sizeof(int));
   *temp = 6;
   n = temp;
}

int main(void)
{
    int number = 5;
    int *number_p = &number;
    bar(number_p);
}

Here, number = 3 after bar(number_p), because we pass to bar the adress of our integer. However, the adress itself is a copy of the original pointer. So, the instruction n = temp; doesn't do anything to number_p, as n is just a local variable.

That's why we need to use a pointer to a pointer.

With the following example, you can modify the original pointer inside the foo function :

void foo(int **n)
{
    **n = 3;
    int *temp = malloc(sizeof(int));
    *temp = 6;
    *n = temp;
}

int main(void)
{
    int number = 5;
    int *number_p = &number;
    foo(&number_p); //We pass the adress of the pointer number_p
}

After foo(&number_p), number is 3, and number_p is a pointer to temp, because we were able to modify the adress itself in foo.

In your example, you need to modify the pointer in the _alloc function, so the signature should be

void _alloc(char **line)

and the pointer should be modified using

*line = malloc(...);

Also, _alloc should be called like this

char* s;
_alloc(&s);

Sorry for my bad english, I did the best in order to be clear.

Chostakovitch
  • 965
  • 1
  • 9
  • 33
  • Is there memory leaks when void bar(int *n) do work with temp. Temp destroy?, but does that memory whom is alloced ( can consider to be leak)? – RadijatoR Feb 17 '15 at 18:30
  • @RadijatoR Yes, there is a memory leak. `temp` is allocated on the stack, so it is destroyed at the end of `bar`, but *temp is still on the heap. In the second example, you need to ˋfree(temp)` at the end of ˋbarˋ. In the third example, you need to ˋfree(number_p)` at the end of ˋmain`. My code was just illustrative. :) – Chostakovitch Feb 17 '15 at 18:36
  • 1
    I accept you answer, because there is something, that i didn't know, but i doesn't have picture yet, about char **, you just wrote "and the pointer should be modified using" . – RadijatoR Feb 17 '15 at 18:40
1

Should be

void _alloc(char **line){
     *line = malloc(sizeof(char) * BUFSIZE);
}

use like this:

/* ... */
char *buf;
_alloc(&buf);

buf is a pointer. You get a pointer to it with &buf, then pass it to _alloc, which dereferences the pointer-to-pointer, getting at buf's value, and changes it to point to newly allocated memory.

C is strictly pass-by-value, so pointers are not treated differently from variables. I.e., to understand this, you could consider the analogy to the following code:

void changeValue(char *chr){
     *chr = 'a';
}

(used like this:)

/* ... */
char buf;
changeValue(&buf);
  • Man, i ask why need char **, i read this what u write in annexed links. – RadijatoR Feb 17 '15 at 15:36
  • Yes it helps. But. Like you post your answer, you in _alloc set, *line = malloc... , so what is **line mind? why is there two *? – RadijatoR Feb 17 '15 at 18:45
  • 1
    @RadijatoR: it's simple. Declaring a variable with an `*` makes it a pointer of some type. For example, `int *a` is a pointer to int. Note that a pointer (`int *`) is also a type in itself. That means you can create a pointer to an object of this type, too. Simply by adding another `*`, like this: `char **a`. Here, `a` is a *pointer to a pointer to char* (i.e. you can say it is the address of the memory where the address of `a` is stored). This is C's pointer arithmetics, and they may be a bit hard to grasp =) –  Feb 17 '15 at 18:55