1

I can't figure out what seems to be the problem that I get a segmentation fault from this:

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

void alloc(unsigned char *data) {
    data = (unsigned char *) malloc(20);
    memset(data, 0, 20);
}

void main() {
    unsigned char *data = NULL;
    int i;
    alloc(data);
    for (i = 0; i < 20; i++) {
        data[i] = i;
        printf("%d ", *(data + i));
    }
    free(data);
}    

Unsigned char is 1 byte so the loop through 20 should be correct

7
  • You need to pass unsigned char** data to the alloc function and then use *data = (unsigned char *) malloc(20); or like Baum mit Augen said use a reference to the pointer. Commented Jun 8, 2015 at 15:09
  • If you try to learn C++ like this, you need to throw your current book / tutorial away and get a better one. Commented Jun 8, 2015 at 15:09
  • Well, looking at it again it's C++ since he's using <cstring>... Otherwise it looks completely like C Commented Jun 8, 2015 at 15:10
  • 1
    If you used a debugger (or even print statements), you should have seen that data was not changed after the call to alloc, and that it is still NULL. That should have given a clue as to what is happening wrt passing-by-value and temporaries. This is why debugging your code is important -- so that you 1) don't waste time asking on SO because you would have known the reason for the issue and/or 2) You would be able to ask a more focused question such as "why hasn't my pointer changed?" Commented Jun 8, 2015 at 15:11
  • Rolled back the changes bc OP specifically asked about C++ both in title and in tags, and this is not C because <cstring>. This edit conflicted with the author's intend. Commented Jun 8, 2015 at 15:27

3 Answers 3

7
void alloc(unsigned char *data) {
    data = (unsigned char *) malloc(20);
    memset(data, 0, 20);
}

modifies a local copy of your pointer. You could pass it by reference to make your example work:

void alloc(unsigned char *&data) {
    data = (unsigned char *) malloc(20);
    memset(data, 0, 20);
}
Sign up to request clarification or add additional context in comments.

3 Comments

if the alloc() function argument is a pointer, shouldn't it be passed by reference by default?
@IoanFulgeanu everything in C++ (except for plain C arrays that decay into pointers) is pass by value by default, even pointers.
@IoanFulgeanu No, the pointer itself still gets passed by value. You seem to be confused because you can use the copy of the pointer to access whatever it points to, which then is the same object the pointer you gave to the function points to.
2

It seems that your program is written in C instead of C++. In C++ you should use operator new [] instead of malloc.

The problem with the function is that function parameters are its local variables. So the function parameter char *data is a copy of its argument declared in main like

unsigned char *data = NULL;

So any changes of the parameter in function alloc do not influence on the original argument. After exiting the function the parameter (local variable) will be destroyed and the original variable in main will not be changed.

You have two approaches. Either you declare the function the following way

void alloc(unsigned char **data) {
    *data = (unsigned char *) malloc( 20 );
    if ( *data ) memset( *data, 0, 20 );
}

and call it like

alloc( &data );

Or you declare the function the following way

unsigned char * alloc() {
    unsigned char *data = (unsigned char *) malloc( 20 );

    if ( data ) memset( data, 0, 20 );

    return data;
}

and call it in main like

data = alloc();

Take into account that function main shall be decalred in C like

int main( void )
^^^

and in C++ like

int main()
^^^

Comments

0

You could also return the pointer, rather than passing it to the function.

unsigned char *alloc() {
    unsigned char *data = (unsigned char *) malloc(20);
    memset(data, 0, 20);
    return data;
}

And then,

...
unsigned char *data = alloc();
int i;
...

You tagged C++, but your code looks like C. If you really are trying to write C++ you shouldn't be using malloc. Either use new[] or the appropriate smart pointers.

EDIT: You're using void main(). Don't do that. What should main() return in C and C++?

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.