简体   繁体   English

c中使用char 2d数组的分割错误

[英]segmentation fault using char 2d array in c

I nead to create a 2d char arry looking like that: 我需要创建一个看起来像这样的2d char arry:

----   
|..|
|..|
----

to do that i wrote a function numed Build_Screen looking like that 为此,我编写了一个编号为Build_Screen的函数,看起来像那样

#include<stdio.h>
#include"build.h"


void Build_Screen(char **c, int w, int k)
{
    int i=0, j=0;
    for(; i<w;i++)
    {
        j=0;
        for(; j<k;j++)
        {
            if (i==0||i==w-1)
                c[i][j]='-';
            else
            {
                if(j==0||j==k-1)
                    c[i][j]='|';
                else
                    c[i][j]='.';
            }
        }
    }
}

when i tried to run that like that 当我试图那样跑

char screen[5][5];
Build_Screen(screen, 5, 5);

it caused segmentation foult. 它导致分割。 how do i fix that? 我该如何解决?

The problem is that your function taking 问题是您的功能正在使用

char **

is not the same as char[5][5] so just change char[5][5]所以只需更改

void Build_Screen(char **c, int w, int k)

with

void Build_Screen(char c[5][5], int w, int k)

You have to pass the array, not a pointer to char pointer , you can see here , it's explained. 你必须通过数组,而不是一个pointerchar pointer ,你可以看到在这里 ,它的解释。

If you don't know the size before hand, then use malloc this way 如果您事先不知道大小,请以这种方式使用malloc

void Build_Screen(char **c, int w, int k)
{
    int i, j;
    for(i=0;i<w;i++)
    {
        for(j=0;j<k;j++)
        {
            if (i == 0 || i == w-1)
                c[i][j] = '-';
            else
            {
                if(j==0||j==k-1)
                    c[i][j]='|';
                else
                    c[i][j]='.';
            }
        }
    }
}

int main(int argc, char **argv)
{
    char **screen;
    int i, rowCount, columnCount;

    rowCount = 5;
    columnCount = 5;

    screen = malloc(rowCount * sizeof(char *));
    if (screen == NULL)
        return -1;

    for (i = 0 ; i < rowCount ; i++)
    {
        screen[i] = malloc(columnCount);
        if (screen[i] == NULL)
        {
            i -= 1;
            for( ; i >= 0 ; i--)
                free(screen[i]);
            free(screen);
            return -1;
        }
    }
    Build_Screen(screen, rowCount, columnCount);

    /* finished using it */
    for (i = 0 ; i < rowCount ; i++)
        free(screen[i]);
    free(screen);

    return 0;
}

notice that I am assuming that you will print the rows without using printf or similar functions, if you are going to, then just add a terminating '\\0' at the end of the strings. 请注意,我假设您将在不使用printf或类似函数的情况下打印行,如果要这样做,则只需在字符串的末尾添加一个终止符'\\0'

Actually, when you state : 实际上,当您声明:

char screen[5][5];

What is happening ? 怎么了 ? It allocates 5*5*sizeof (char) contiguous bytes on the stack, pointed by screen[0] . 它在堆栈上分配5*5*sizeof (char)个连续字节,由screen[0]指向。 Thus, screen[0][1] is strictly equivalent to *(screen[0] + 0*5 + 1); 因此, screen[0][1]严格等于*(screen[0] + 0*5 + 1);

Your problem can be easily resolved by changing your function's signature to 您可以通过将函数的签名更改为来轻松解决问题

void Build_Screen(char c[5][5], int w, int k);

I guess you want to have a function that works with any size of maps. 我想您想拥有一个适用于任何尺寸地图的功能。 This won't happen with genuine 2D array in C, except in C99. 在C中使用正版2D阵列将不会发生这种情况,但在C99中除外。 More details available here . 此处有更多详细信息。

A char[5][5] is a 2D array and not a char**. char [5] [5]是2D数组,而不是 char **。 It is a contiguous zone of 25 chars : 这是一个25个字符的连续区域:

00 01 02 03 04 10 11 12 13 14 20 ...

A char ** is a pointer to a pointer to a char : char **是指向char **的指针的指针

0  -> 00 01 02 03 04
1  -> 10 11 12 13 14
2  -> 20 ...
3  -> 30 ...
4  -> 40 ...

You must declare it that way : 您必须这样声明:

char ascreen[5][5];
char *screen[5];
for(i=0; i<5; i++) screen[i] = &(ascreen[i][0]);
Build_Screen(screen, 5, 5);

Edit: here is a full program : 编辑:这是一个完整的程序:

#include<stdio.h>

void Build_Screen(char **c, int w, int k)
{
    int i=0, j=0;
    for(; i<w;i++)
    {
        j=0;
        for(; j<k;j++)
        {
            if (i==0||i==w-1)
                c[i][j]='-';
            else
            {
                if(j==0||j==k-1)
                    c[i][j]='|';
                else
                    c[i][j]='.';
            }
        }
    }
}

int main() {
    int i;
    char ascreen[5][5];
    char *screen[5];
    for(i=0; i<5; i++) screen[i] = &(ascreen[i][0]);
    Build_Screen(screen, 5, 5);
    for(i=0; i<5; i++) {
        printf("%.5s\n", screen[i]); /* or printf("%.5s\n", ascreen[i]); */
    }
    return 0;
}

and the output is : 输出为:

-----
|...|
|...|
|...|
-----

You can also access your array as a one dimensional array. 您还可以将数组作为一维数组访问。 The following code was sucessfully tested locally: 以下代码已在本地成功测试:

void Build_Screen(char* c, int w, int k)
{
    int i = 0, j = 0;
    for (; i<w; i++)
    {
        j = 0;
        for (; j<k; j++)
        {
            if (i == 0 || i == w - 1)
                c[i*w+j] = '-';
            else
            {
                if (j == 0 || j == k - 1)
                    c[i*w + j] = '|';
                else
                    c[i*w + j] = '.';
            }
        }
    }
}

int main()
{

    char screen[5][5];
    Build_Screen((char*)screen, 5, 5);
}

As @iharob wrote, your function's signature is not working as you expect. 正如@iharob所写,函数的签名未按预期工作。 You should use a single pointer char *c and index the array like this or something similar: 您应该使用单个指针char * c并像这样或类似的方式索引数组:

c[i+w*j]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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