为什么会出现segmentation Fault错误
Why is the segmentation Fault error occuring
我遇到错误分段错误(核心已转储)
我已经将它缩小到函数 threadx 中的这些行
while (colatz_nums[j] != 1)
{j++;
if ((m % 2)==0)
{ colatz_nums[j] = m/2;}
else
{colatz_nums[j] = 3 * m +1;}
}
如果我删除这些行,我就不会收到错误。
我添加了一个 while 循环测试并且它有效
所以它一定是这些行中的东西。
错误请指出
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> // pid_t
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <pthread.h>
#define N 2
void *thread (void *vargp);
void *threadx(void *vargp);
char **ptr;
int fib_nums[25] ;
int colatz_nums[25];
int last_collatz = 0;
int main()
{
int i;
pthread_t tid[2];
char *msgs[N] = {
"Hello from foo",
"Hello from bar"
};
printf("Parent thread started with PID= %d and parent PID %d\n", getpid(), getppid());
ptr = msgs;
pthread_create(&tid[0], NULL, thread, (void *)1);
printf(" 1st thread started with PID= %d and parent PID %d\n", getpid(), getppid());
pthread_create(&tid[1], NULL, threadx, (void *)2 );
printf("2nd thread started with PID= %d and parent PID %d\n", getpid(), getppid());
pthread_join(tid[1], NULL);
pthread_join(tid[0], NULL);
}
void *thread(void *vargp)
{
int myid = (int)vargp;
static int cnt = 0;
printf(" thread ");
int i=cnt;
for (;i <10 ;i=i+1)
{
printf("[%d] %d\n",myid, i);
sleep(cnt);
}
return NULL;
}
void *threadx(void *vargp )
{
int myid = (int)vargp;
static int cnt = 0;
printf(" threadx \n" );
int j = 0;
int m = 8;
colatz_nums[0] = 8;
while (colatz_nums[j] != 1)
{
j++;
if ((m % 2)==0)
{
colatz_nums[j] = m/2;
}
else
{
colatz_nums[j] = 3 * m +1;
}
}
last_collatz = j;
for (j=0; j <= last_collatz; j++)
printf ( " j %d",colatz_nums[j]);
printf ( "\n");
return NULL;
}
您从不检查 colatz_nums
的界限。您正在使用 j
访问它并递增它而不将其限制为 24.
你先执行
colatz_nums[0] = 8
将数组的第一个值设置为 8。然后你将它与 1 进行比较,它不是,然后循环直到在数组中找到 1。
你的循环中的问题是你首先递增 j
然后设置位于索引 j
的值(这是你将在下一轮循环中测试 1 的下一个值)一个永远不会是 1 的值(4 或 25,但在你的例子中总是 4)。
然后你将永远循环直到发生崩溃(越界访问)。
m
从不 改变,所以 colatz_nums[j]
连续 被设置为 4
(因为 m
是八,一个偶数),直到你 运行 离开数组末尾的那一点。
您可以通过简单地将此行作为 while
循环中的最后一行来解决此问题:
m = colatz_nums[j];
或将其重写为更安全的变体,避免未定义的行为:
while (colatz_nums[j] != 1) {
j++;
if ((m % 2)==0)
m = m / 2;
else
m = 3 * m + 1;
if (j == sizeof(colatz_nums) / sizeof(colatz_nums[0])) {
fprintf (stderr, "Buffer overflow\n");
exit (1); // or some other method of stopping
}
colatz_nums[j] = m;
}
我遇到错误分段错误(核心已转储)
我已经将它缩小到函数 threadx 中的这些行
while (colatz_nums[j] != 1)
{j++;
if ((m % 2)==0)
{ colatz_nums[j] = m/2;}
else
{colatz_nums[j] = 3 * m +1;}
}
如果我删除这些行,我就不会收到错误。 我添加了一个 while 循环测试并且它有效 所以它一定是这些行中的东西。 错误请指出
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> // pid_t
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <pthread.h>
#define N 2
void *thread (void *vargp);
void *threadx(void *vargp);
char **ptr;
int fib_nums[25] ;
int colatz_nums[25];
int last_collatz = 0;
int main()
{
int i;
pthread_t tid[2];
char *msgs[N] = {
"Hello from foo",
"Hello from bar"
};
printf("Parent thread started with PID= %d and parent PID %d\n", getpid(), getppid());
ptr = msgs;
pthread_create(&tid[0], NULL, thread, (void *)1);
printf(" 1st thread started with PID= %d and parent PID %d\n", getpid(), getppid());
pthread_create(&tid[1], NULL, threadx, (void *)2 );
printf("2nd thread started with PID= %d and parent PID %d\n", getpid(), getppid());
pthread_join(tid[1], NULL);
pthread_join(tid[0], NULL);
}
void *thread(void *vargp)
{
int myid = (int)vargp;
static int cnt = 0;
printf(" thread ");
int i=cnt;
for (;i <10 ;i=i+1)
{
printf("[%d] %d\n",myid, i);
sleep(cnt);
}
return NULL;
}
void *threadx(void *vargp )
{
int myid = (int)vargp;
static int cnt = 0;
printf(" threadx \n" );
int j = 0;
int m = 8;
colatz_nums[0] = 8;
while (colatz_nums[j] != 1)
{
j++;
if ((m % 2)==0)
{
colatz_nums[j] = m/2;
}
else
{
colatz_nums[j] = 3 * m +1;
}
}
last_collatz = j;
for (j=0; j <= last_collatz; j++)
printf ( " j %d",colatz_nums[j]);
printf ( "\n");
return NULL;
}
您从不检查 colatz_nums
的界限。您正在使用 j
访问它并递增它而不将其限制为 24.
你先执行
colatz_nums[0] = 8
将数组的第一个值设置为 8。然后你将它与 1 进行比较,它不是,然后循环直到在数组中找到 1。
你的循环中的问题是你首先递增 j
然后设置位于索引 j
的值(这是你将在下一轮循环中测试 1 的下一个值)一个永远不会是 1 的值(4 或 25,但在你的例子中总是 4)。
然后你将永远循环直到发生崩溃(越界访问)。
m
从不 改变,所以 colatz_nums[j]
连续 被设置为 4
(因为 m
是八,一个偶数),直到你 运行 离开数组末尾的那一点。
您可以通过简单地将此行作为 while
循环中的最后一行来解决此问题:
m = colatz_nums[j];
或将其重写为更安全的变体,避免未定义的行为:
while (colatz_nums[j] != 1) {
j++;
if ((m % 2)==0)
m = m / 2;
else
m = 3 * m + 1;
if (j == sizeof(colatz_nums) / sizeof(colatz_nums[0])) {
fprintf (stderr, "Buffer overflow\n");
exit (1); // or some other method of stopping
}
colatz_nums[j] = m;
}