Thread: Segfaulting/memory access for array (Linux)

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    34

    Segfaulting/memory access for array (Linux)

    Whenever I try to access the 3rd element or higher of this 2d array, i keep getting segfaults because apparently i havnt allocated any memory there... but I have.

    Code:
    typedef struct {
        char ***array1
        char ***array2
    } info;
    
    void *thread(void *arg) {
        info b;
        b = *(info *)arg;
        ...
        sscanf(buffer, "%s", *b.array1[pthread_self()-2]);
        ...
    }
         
    
    function {
        ...
        char **x = (char **)malloc(sizeof(char*)*10);
        char **y = (char **)malloc(sizeof(char*)*10);
        for (i=0;i<10;i++) {
            x[i] = (char*)malloc(sizeof(char)*50);
            y[i] = (char*)malloc(sizeof(char)*60);
        }
        info a;
        a.array1 = &x;
        a.array2 = &y;
        while(1) {
            ...
            pthread_create(&tid,NULL,thread, (void *)&a);
            pthread_join(tid, NULL);
        }
    }
    I just put in the code that was relevant to the problem. When pthread_self() becomes 4 or greater, I get a segfault because of memory access (thats what gdb says).

    This is on unix/linux btw. I don't know if that would limit the number of people being able to help me with this.

  2. #2
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Not sure if you know it already, but Linux has a very powerful memory debugger called Valgrind that would identify tons of memory errors.

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Blasz View Post
    This is on unix/linux btw. I don't know if that would limit the number of people being able to help me with this.
    You'd be amazed. I'd guess more than half the people on here use linux often enough.

    I see some possible problems:
    Code:
        char ***array1
        char **x = (char **)malloc(sizeof(char*)*10);
        a.array1 = &x;
    Why do you want to do this? What's wrong with:
    Code:
        char **array1
        char **x = malloc(sizeof(char*)*10);
        a.array1 = x;
    Certainly, this could lead to wonky stuff here:
    Code:
        sscanf(buffer, "%s", *b.array1[pthread_self()-2]);
    Which would be better written:
    Code:
        sscanf(buffer, "%s", b->array1[pthread_self()-2]);
    Otherwise, it could mean:
    Code:
    *(b.array1[pthread_self()-2])
    // which is not the same as 
    (*b).array1[pthread_self()-2]
    Altho I'm not too sure what you want because of the triple pointer...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Apr 2010
    Posts
    34
    This is actually run on solaris so I can't use that I'm afraid.

    EDIT: Triple pointer is a pointer to an array of strings.
    Last edited by Blasz; 06-06-2010 at 10:24 AM.

  5. #5
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    I don't see anything wrong with the code, maybe the problem is elsewhere.

    Can you post minimal compilable code that shows the problem?

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Blasz View Post
    EDIT: Triple pointer is a pointer to an array of strings.
    Yes, but what do you need that for if all you want is an array of strings?

    A single char:
    char s;

    A char pointer, which could point to an array of chars (aka, a string):
    char *s;

    A pointer to a pointer, which would be an array of strings:
    char **s;

    What you are doing with the pointer to a pointer to a pointer (***s) is like doing this:
    Code:
    int *p = malloc(sizeof(int)*10) // array of ints
    int **ptp = &p;  // a pointer to an array of ints
    p[2] = 5;  // assign to third element of p
    (*ptp)[2] = 5;  // indirect assignment to third element of p
    Why use ptp at all there? Get it?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Apr 2010
    Posts
    34
    Multiple threads will be updating the array of strings and therefore when the struct is passed to them in the form of pthread_create, they can freely edit/share variables through the use of pointers in the struct.

    @fish,
    I can PM you my code if you want, I do not want to display it publicly.

    Oh and i forgot to add if it wasnt obvious already, the segfault happens at the sscanf line.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Blasz View Post
    Multiple threads will be updating the array of strings and therefore when the struct is passed to them in the form of pthread_create, they can freely edit/share variables through the use of pointers in the struct.
    Are you using mutexes or some other form of locking? If not, I'm not sure if that will cause a segfault but it certainly will cause a screw-up.

    Also, you need to justify your use of this *** since, in fact, it is not compatible with the sscanf.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    @fish,
    I can PM you my code if you want, I do not want to display it publicly.
    Ah no, that's fine then.

    No one should ever trust me with their code .

    I wasn't suggesting posting the actual code, but something like what you posted, with stubs added in to make it compile (and crash).

  10. #10
    Registered User
    Join Date
    Apr 2010
    Posts
    34
    Quote Originally Posted by MK27 View Post
    Are you using mutexes or some other form of locking? If not, I'm not sure if that will cause a segfault but it certainly will cause a screw-up.

    Also, you need to justify your use of this *** since, in fact, it is not compatible with the sscanf.
    I will be using mutexes but the lack of them at the moment is not causing the segfault. What do you mean the *** is not compatible with sscanf?

    The ***, as i said earlier, is a pointer to an array of strings in the parent thread, which will let the other threads read/write to it.

    *b.array[0], *b.array[1] work fine, but whenever it gets to *b.array[2] it causes a segfault. Doesn't matter what values i put in the malloc, (even 0....)

  11. #11
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Blasz View Post
    What do you mean the *** is not compatible with sscanf?
    I already explained this in my previous posts, you can go back and read them after you try this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, const char *argv[]) {
    	int i;
    	char **eg = malloc(sizeof(char*)*10),
    		***ptptp = &eg, buffer[16];
    
    	for (i=0;i<10;i++) {
    		eg[i] = malloc(16);
    		sprintf(buffer, "string#%d", i);
    		sscanf(buffer, "%s", eg[i]);
    //		sscanf(buffer, "%s", *ptptp[i]);
    		puts(eg[i]);
    	}
    
    	return 0;
    }
    The red commented out line is what you are doing. If I compile and run this as is, I get:
    string#0
    string#1
    string#2
    string#3
    string#4
    string#5
    string#6
    string#7
    string#8
    string#9


    If I comment out the correct one and do it your way, I get:
    string#0
    Segmentation fault


    End of story! You do not need to use the *** at all for an array of strings. An array of strings is contained in a char**.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #12
    Registered User
    Join Date
    Apr 2010
    Posts
    34
    If you change
    Code:
    //		sscanf(buffer, "%s", *ptptp[i]);
    to
    Code:
    //		sscanf(buffer, "%s", (*ptptp)[i]);
    it works, I may have stumbled upon an answer to my problem perhaps.

    EDIT:YES!, it fixed my problem, it seems like the pointer needs to be dereferenced before the array element is chosen.
    Last edited by Blasz; 06-06-2010 at 11:44 AM.

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Blasz View Post
    it works, I may have stumbled upon an answer to my problem perhaps.
    Yes, that was in my first post. However, the real point is that you are using a completely pointless added level of indirection (that's in that post too). So a hack to solve an unnecessary mistake is not the answer: fix the original mistake.

    You might want to read this, it is slightly sarcastic but explains the issue further:
    Three Star Programmer
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Registered User
    Join Date
    Apr 2010
    Posts
    34
    Your first post didn't have the right brackets though.

    And my added level of indirection is not pointless as I have said....

    Anyway, thanks for your help. I appreciate the time you have given to helping me.

  15. #15
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Blasz View Post
    Your first post didn't have the right brackets though.
    No, I was hinting at the issue and not really trying to solve it until I got an understanding of why you wanted to do something that looks like a simple mistake (too many levels of indirection). Like I said, it would be irresponsible to suggest a hack fix to a problem instead of suggesting you fix the real problem. The solution I did give in that post was such a fix (the proper one, not the "cover it up" one). But that's your choice.

    And my added level of indirection is not pointless as I have said....
    If you have some secret reason for it okay, but based on what you've posted so far, you do not. I am not saying this to be mean, but to help you, because if you think "it is not pointless" you are wrong, and this indicates there is a fundamental issue about pointers you do not understand.

    If you want to be clear and explain yourself, you will learn a lot quicker than if you pretend to know everything Anyway, good luck and have fun.
    Last edited by MK27; 06-06-2010 at 11:59 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Windows-Linux Comparison
    By Yarin in forum General Discussions
    Replies: 80
    Last Post: 02-14-2010, 05:10 PM
  2. Linux Version reccomendation
    By Pobega in forum A Brief History of Cprogramming.com
    Replies: 28
    Last Post: 10-05-2006, 06:48 PM
  3. Why Linux, for the average user?
    By Hunter2 in forum A Brief History of Cprogramming.com
    Replies: 32
    Last Post: 07-07-2006, 02:36 PM
  4. Which distribution of Linux should I get?
    By joshdick in forum A Brief History of Cprogramming.com
    Replies: 50
    Last Post: 01-19-2003, 09:26 AM
  5. Linux for Windows!
    By Strut in forum Linux Programming
    Replies: 2
    Last Post: 12-25-2002, 11:36 AM