![](/img/trans.png)
[英]Segmentation fault in 2D array unsigned char using calloc in C
[英]segmentation fault using char 2d array in c
我需要創建一個看起來像這樣的2d char arry:
----
|..|
|..|
----
為此,我編寫了一個編號為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]='.';
}
}
}
}
當我試圖那樣跑
char screen[5][5];
Build_Screen(screen, 5, 5);
它導致分割。 我該如何解決?
問題是您的功能正在使用
char **
與char[5][5]
所以只需更改
void Build_Screen(char **c, int w, int k)
與
void Build_Screen(char c[5][5], int w, int k)
你必須通過數組,而不是一個pointer
到char pointer
,你可以看到在這里 ,它的解釋。
如果您事先不知道大小,請以這種方式使用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;
}
請注意,我假設您將在不使用printf
或類似函數的情況下打印行,如果要這樣做,則只需在字符串的末尾添加一個終止符'\\0'
。
實際上,當您聲明:
char screen[5][5];
怎么了 ? 它在堆棧上分配5*5*sizeof (char)
個連續字節,由screen[0]
指向。 因此, screen[0][1]
嚴格等於*(screen[0] + 0*5 + 1);
您可以通過將函數的簽名更改為來輕松解決問題
void Build_Screen(char c[5][5], int w, int k);
我想您想擁有一個適用於任何尺寸地圖的功能。 在C中使用正版2D陣列將不會發生這種情況,但在C99中除外。 此處有更多詳細信息。
char [5] [5]是2D數組,而不是 char **。 這是一個25個字符的連續區域:
00 01 02 03 04 10 11 12 13 14 20 ...
char **
是指向char **
的指針的指針 :
0 -> 00 01 02 03 04
1 -> 10 11 12 13 14
2 -> 20 ...
3 -> 30 ...
4 -> 40 ...
您必須這樣聲明:
char ascreen[5][5];
char *screen[5];
for(i=0; i<5; i++) screen[i] = &(ascreen[i][0]);
Build_Screen(screen, 5, 5);
編輯:這是一個完整的程序:
#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;
}
輸出為:
-----
|...|
|...|
|...|
-----
您還可以將數組作為一維數組訪問。 以下代碼已在本地成功測試:
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);
}
正如@iharob所寫,函數的簽名未按預期工作。 您應該使用單個指針char * c並像這樣或類似的方式索引數組:
c[i+w*j]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.