0

我在 Ubuntu 上使用 Eclipse C/C++ IDE,并试图将 2D 定义char为父子进程之间的共享内存,并且正在使用它:

void fill(char **p)
{
    printf ("int i=0;\n");
    int i=0;
    printf ("int j=0;\n");
    int j=0;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            p[i][j]=' ';
        }
    }
}


int shmid;
char **shmPtr;
if(shmid = shmget(2000, sizeof(char[3][3]), 0)!=-1)
{
    shmPtr = shmat(shmid, 0, 0); //attach shared memory to pointer
    fill(shmPtr);
}

这是定义数组的正确方法吗?在尝试填充这个数组时,我得到一个

分段故障

.

4

2 回答 2

1

正是我所怀疑的。二维数组不是双指针。

void fill(char p[3][3])
{
    int i, j;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            p[i][j] = ' ';
        }
    }
}

int shmid = shmget(2000, sizeof(char[3][3]), 0);
char (*shmPtr)[3] = shmat(shmid, 0, 0);
fill(shmPtr);
于 2013-02-18T17:18:00.633 回答
0

使用共享内存(实际上通常是动态分配的)时,我建议您使用以下算法来访问 2D 数据,而不是“[i][j]”:

*(pointer + row * ncols + col) = ...

此外,您应该使用字符“”而不是字符串“”(这是一个 const char*)。在您的示例中,填充函数将类似于:

void fill(char *p, int rows, int cols)
{
    int i, j;
    for(i=0; i<rows; i++)
    {
        for(j=0;j<cols;j++)
        {
            /* p[i][j] = ' '; */
            *(p + i*cols + j) = ' ';
        }
    }
}

另一个更好的是使用 memset:

void fill(char *p, int rows, int cols)
{
    memset(p, (int)' ', cols*rows);
}

而且,一个主要样本:

int main()
{
    int shmid;
    void *shmPtr;
    char *shm;
    /* create the shared segment */
    if ((shmid = shmget(IPC_PRIVATE, sizeof(char) * (3*3), IPC_CREAT | 0666)) < 0) {
        perror("shmget");
        exit(1);
    }
    /* use it on the parent process */
    if ((shmPtr = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }
    shm = (char *)shmPtr;
    /* fill with spaces */
    fill(shmPtr, 3, 3);
    int i;
    /* some forks, sample */
    for (i = 0; i < 10; i++) {
        if (fork() == 0) {
                ... child workd ...
        }
    }
    ...
    shmctl(shmid, IPC_RMID, NULL);
    return 0;
}

还有一件事,如果可能的话,尝试使用mmap而不是 SysV 共享内存。

于 2013-02-18T17:31:06.783 回答