简体   繁体   中英

Memorymanagement in C, passing pointers in functions, segmentation fault

I have three files:

something.h

typedef struct {
    int size_t;
    char *c;
} p;

p ** createMatrix(int r, int c);

void printMatrix(p **matrix, const int r, const int c);

something.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "something.h"

p **
createMatrix(int r, int c)
{
    int rowsize=r*2+1;
    int colsize=c*2+1;

    /* memory alloc of rows */
    p **matrix=malloc(rowsize*sizeof(p *));
    int k;
    for(k=0; k<rowsize; k++)
    {
        /* memory alloc of columns */
        matrix[k]=malloc(colsize*sizeof(p));
    } 
    int i, j;
    for(i=0; i<rowsize; i++)
    {
        for(j=0; j<colsize; j++)
        {
            /* columns is between letters */
            if(j%2!=0)
            {   
                matrix[i][j].size_t=7;
                matrix[i][j].c=malloc(8*sizeof(char));
                strcpy(matrix[i][j].c,"       ");
            }
            else if(i%2==0 && j%2==0)
            {
                matrix[i][j].size_t=1;
                matrix[i][j].c=malloc(sizeof(char));
                *(matrix[i][j].c)='a';
            }
            else
            {
                matrix[i][j].size_t=1;
                matrix[i][j].c=malloc(sizeof(char));
                *(matrix[i][j].c)=' ';
            }
        }
    }       
    return matrix;
}

void
printMatrix(p **matrix, const int r, const int c)
{
    int rowsize=r*2+1;
    int colsize=c*2+1;
    printf("\n");
    int i, j;
    for(i=0; i<rowsize; i++)
    {
        printf("\t");
        for(j=0; j<colsize; j++)
        {
            if(matrix[i][j].size_t==1)
                printf("%c", *matrix[i][j].c);
            else
                printf("%s", matrix[i][j].c);

        }
        printf("\n");
    }
    printf("\n");
 }

main.c

#include <stdlib.h>
#include <stdio.h>
#include "something.h"    

void
printMenufunction(p **matrix, int rows, int cols)
{
    int rowsize=rows*2+1;
    int colsize=cols*2+1;
    /* memory alloc of rows */
    matrix=malloc(rowsize*sizeof(p *));
    int i;
    for(i=0; i<rowsize; i++)
    /* memory alloc of columns */
        matrix[i]=malloc(colsize*sizeof(p));
    matrix=createMatrix(rows, cols);
}

int
main(void)
{
    int rows, cols;
    p **matrix;
    char stringtemp[3];
    printf("ask for row and col in form (5x5):\n");
    scanf("%s", stringtemp);
    sscanf(stringtemp, "%dx%d", &rows, &cols);
    printMenufunction(matrix, rows, cols);
    printMatrix(matrix, rows, cols);
    return 0;
}

This code sample that is a simplified version of my prog gives me a segmentation fault. I have debugged it with the gdb so I know its somewhere amongst these lines that the fault lies. I would be grateful for some help, thanks.

UPDATE: I can't debug this version. My old prog with alot more code told me it was along this area, but at least I can't figure out where? So thats why I can't post what line exactly that makes the segmentation fault. If i knew I think I could have handled the problem my self. I hoped some one could see it more clearly than me..

As C is a pass-by-value language, any assignment to a function argument modifies only the local copy of the argument, so when printMenufunction returns, matrix is still not initialized.

You need to pass the pointers to matrix by reference:

printMenufunction(&matrix, rows, cols);
printMatrix(&matrix, rows, cols);

and dereference inside the functions. For example:

//                       v Pointer to the double-pointer
void printMenufunction(p ***matrix, int rows, int cols)
{
    int rowsize=rows*2+1;
    int colsize=cols*2+1;
    /* memory alloc of rows */
//  v Dereferencing the pointer
    *matrix=malloc(rowsize*sizeof(p *));
   // ...
}

First of all, it would help us a lot for you to tell us which line gdb indicated was at fault instead of just saying, "it's somewhere in these lines." gdb should be able to tell you exactly which line triggered the error.

Having said that, here's a candidate:

char *stringtemp;
printf("ask for row and col in form (5x5):\n");
scanf("%s", stringtemp);

stringtemp hasn't been assigned to point anywhere meaningful; all you have is a pointer whose initial value is indeterminate . So that's one potential segfault. Either allocate a buffer for stringtemp to point to, or just allocate it as an array of char :

char stringtemp[SOME_SIZE]; // where SOME_SIZE is as big as you need.

Why are you allocating the matrix in printMenuFunction ?! Why aren't you using your createMatrix function?!

EDIT

I hate getting old; I completely missed that createMatrix is being called from printMenuFunction (which means that the malloc calls in printMenuFunction are redundant and need to be eliminated).

Rewrite your printMenuFunction as follows:

void printMenuFunction(p ***matrix, int rows, int cols)
{
  *matrix = createMatrix(rows, cols);
}

Note that within that function, if you need to access an element of matrix , you will need to dereference it before applying a subscript, such as

(*matrix)[i][j].size = ...;

Rewrite your main as follows:

int
main(void)
{
    int rows, cols;
    p **matrix;
    char stringtemp[3]; // 3 is not big enough to hold a string like "5x5";
                        // that requires an array size of *at least* 4.  
                        // "10x10" would require 6 characters.  You need
                        // an extra character for the 0 terminator.

    printf("ask for row and col in form (5x5):\n");
    scanf("%s", stringtemp);
    sscanf(stringtemp, "%dx%d", &rows, &cols);
    printMenufunction(&matrix, rows, cols); // note the & in front of matrix
    printMatrix(matrix, rows, cols);
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM