c - C 中的内存管理、在函数中传递指针、段错误

标签 c memory-management

我有三个文件:

某事.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);

某事.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;
}

这个代码示例是我的程序的简化版本,给我带来了段错误。我已经用 gdb 调试了它,所以我知道错误就在这些行中的某个地方。如果您能提供一些帮助,我将不胜感激,谢谢。

更新: 我无法调试这个版本。我的旧程序有更多代码告诉我它就在这个区域,但至少我不知道在哪里?所以这就是为什么我无法准确发布导致段错误的行。如果我知道的话,我想我可以自己解决这个问题。我希望有人能比我看得更清楚..

最佳答案

首先,如果您能告诉我们 gdb 指示的哪一行有问题,而不是仅仅说“它位于这些行中的某处”,这会对我们有很大帮助。 ”。 gdb 应该能够准确地告诉您哪一行触发了错误。

话虽如此,这里有一个候选人:

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

stringtemp 尚未分配给任何有意义的点;您所拥有的只是一个初始值为不确定的指针。所以这是一个潜在的段错误。要么为 stringtemp 分配一个指向的缓冲区,要么将其分配为 char 数组:

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

为什么要在 printMenuFunction 中分配矩阵?!为什么不使用 createMatrix 函数?!

编辑

我讨厌变老;我完全错过了从 printMenuFunction 调用 createMatrix (这意味着 printMenuFunction 中的 malloc 调用是多余的,并且需要消除)。

重写您的printMenuFunction如下:

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

请注意,在该函数中,如果您需要访问matrix的元素,则需要在应用下标之前取消引用,例如

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

重写您的main,如下所示:

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;
}

关于c - C 中的内存管理、在函数中传递指针、段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13277707/

相关文章:

c - 生成一个 secret 数字并用 C 猜测它

c - 链表只抓取文件内容的最后输入

c - 为什么将 4 字节参数传递给需要 2 字节参数的函数有效?

c++ - 如何分配堆指针

iphone - UIViewController内存泄漏问题

java - 重用单个对象而不是创建新对象

iphone - 如何使用iPhone SDK下载大文件并避免内存使用问题?

c - 为什么在 XV6 中常量 PHYSTOP 被定义为 0xE000000?

c - 使用其内核命名空间 PID 从全局范围内终止进程

c++ - 解码由 GetAdaptersAddresses Windows API 函数返回到内存中的 IP_ADAPTER_ADDRESSES 结构?