【问题标题】:segmentation fault (core dumped) - what is wrong in my code分段错误(核心转储) - 我的代码有什么问题
【发布时间】:2016-03-10 01:48:30
【问题描述】:

有人知道我为什么会收到“分段错误(核心转储)”消息吗?怎么了?在我看来,问题出在数组上。我知道“分段错误”意味着我试图访问我无权访问的内存。

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, const char* argv[])
{
    int shmid;
    int i, j;
    int glos;
    pid_t pid;
    key_t key;
    long *wyniki;

    key = ftok("/home/sebastian", 2);

    shmid = shmget(key, 20 * sizeof(long), IPC_CREAT);

    if (shmid == -1) {
        printf("Error - New memory segment");
    }
    else {
        printf("My memory segment: %d\n", shmid);
        wyniki = (long*) shmat(shmid, 0, 0);

        for (i = 0; i < 5; i++) {
            wyniki[i] = 0;
        }

        // Creating new processes
        for (i = 0; i < 20; i++) {
            pid = fork();
            if (pid == 0) {
                srand48(time(NULL) + getpid());
                for (j = 0; j < 1000000; j++) {
                    glos = rand() % 5;
                    wyniki[glos] += 1;
                }
            }
            else {
                printf("ERROR - PROCESSES");
            }
        }
    }

return 0;
}

【问题讨论】:

  • 你用过gdb吗?段错误之前的变量值是多少? ftok 成功了吗?你应该check its return value以防万一。
  • 用 -g 编译程序,使用 gdb 运行它,这将显示它失败的行
  • ftok 不返回 -1。
  • 你#include了哪些头文件?
  • 调试器说 ftok 中没有这样的文件或目录。另外,当我想重置数组wyniki 时会引发分段错误

标签: c unix gcc segmentation-fault


【解决方案1】:

修复“创建的进程过多”问题:

改变这个:

    // Creating new processes
    for (i = 0; i < 20; i++) {
        pid = fork();
        if (pid == 0) {
            srand48(time(NULL) + getpid());
            for (j = 0; j < 1000000; j++) {
                glos = rand() % 5;
                wyniki[glos] += 1;
            }
        }
        else {
            printf("ERROR - PROCESSES");
        }
    }

到这里:

    // Creating new processes
    for (i = 0; i < 20; i++) 
    {
        pid = fork();
        if (pid == 0) 
        { // child process
            srand48(time(NULL) + getpid());
            for (j = 0; j < 1000000; j++) 
            {
                glos = rand() % 5;
                wyniki[glos] += 1;
            }
            exit();
        }

        else if( 0 > pid)
        { // error occurred
            perror( "fork() failed" );
            printf("ERROR - PROCESSES\n");
        }

        //else
        //{ // parent process
        //    ; 
        //}
    } // end: for 20 child processes

【讨论】:

  • 几个小时前我修好了,和现在写的一模一样:)
【解决方案2】:

您在未正确设置权限位的情况下创建了共享内存段,因此您无权访问该内存。

根据shmget()man page

   int shmget(key_t key, size_t size, int shmflg);
   ...
   In addition to the above flags, the least significant 9 bits of
   shmflg specify the permissions granted to the owner, group, and
   others.  These bits have the same format, and the same meaning, as
   the mode argument of open(2).  Presently, execute permissions are not
   used by the system.

需要指定共享内存段的权限:

shmid=shmget(key, 20 * sizeof(long), IPC_CREAT | 0600);

或使用06400660 或符号模式。

但首先您可能必须使用 ipcrm 删除现有段。

【讨论】:

  • 这就是原因。但是 shmget 给了我-1的价值。它与现有细分相关?
  • @Se-BASS-tian 可能。查看ipcs -m 的输出,并删除您帐户拥有的所有段,假设您没有以root 身份运行并且没有大量其他共享内存段用于其他目的。见man7.org/linux/man-pages/man1/ipcs.1.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 1970-01-01
  • 2018-04-03
  • 1970-01-01
相关资源
最近更新 更多