在多个函数中使用全局变量后发生分段错误
Segmentation Fault occurs after using global variable in several function
我目前正在编写我的学士项目,其中包含一个 RFB 客户端和一个共享内存。 RFB 客户端的初始化已完成,共享内存已创建。我的老师告诉我解耦代码,我写了几个函数并为共享内存使用了一个全局变量。
但是现在在尝试读取全局变量的内容时发生了段错误。我调试了代码,发现:全局变量 "my_shm" 的内容始终为“0x00”:-/
你能帮帮我吗?
这些是出现问题的代码部分:
(我知道,这是一个很长的代码,但是只发送其中的一部分是没有用的...)
char *my_shm; --> //global variable
int SHM_init (int shmid, char* shm, key_t key, long int size) {
/* Create a new (System V) shared memory segment of the specified size */
shmid = shmget(key, SHM_SIZE, IPC_CREAT|0777);
/* Check if SHM creation was successful */
if (shmid < 0) {
/* DBG: Debug message to show which point of the program has been passed */
DBG_PRINT("C\n");
/* Check if creation failed because of already existing SHM */
if (EEXIST == errno) {
/* DBG: Debug message to show which point of the program has been passed */
DBG_PRINT("CC\n");
/* Delete already existing SHM with shmctl */
shmctl(shmid, IPC_RMID, NULL);
} else {
/* DBG: Debug message to show which point of the program has been passed */
DBG_PRINT("CCC\n");
}
/* Creation and initialization of SHM failed */
return -1;
}
/* Attach the SHM data pointer to the previously created SHM segment */
shm = shmat(shmid, NULL, 0);
if(shm == (char *) -1) {
/* Attaching failed */
return -1;
}
DBG_PRINT("Shared Memory Initialization successful\n");
/* Creation and initialization of shared memory was successful */
return 0;
}
void RFB_update(rfbClient* client) {
DBG_PRINT("RFB_update called\n");
int i,j;
rfbPixelFormat* pformat=&client->format;
DBG_PRINT("A\n");
/*bytesPerPix: variable which stores Bytes per Pixel*/
int bytesPerPix = pformat->bitsPerPixel/8;
DBG_PRINT("B\n");
/*row= width of frame*bytes per Pixel*/
int row=client->width*bytesPerPix;
DBG_PRINT("C\n");
char byte_to_write;
//as long as j is smaller than 128*(width*bytesPerPix)
for(j=0;j<client->height*row;j+=row) {
//as long as i is smaller than 128 * bytesPerPix
for(i=0;i<client->width*bytesPerPix;i+=bytesPerPix) {
/*frameBuff: Pointer on FrameBuffer*/
unsigned char* frameBuff = client->frameBuffer+j+i;
unsigned int v;
if(bytesPerPix==4)
v=(unsigned int*)frameBuff;
byte_to_write = ((v>>pformat->redShift)*256/(pformat->redMax+1));
SHM_write_byte(my_shm,byte_to_write);
byte_to_write = ((v>>pformat->greenShift)*256/(pformat->greenMax+1));
SHM_write_byte(my_shm,byte_to_write);
byte_to_write = ((v>>pformat->blueShift)*256/(pformat->blueMax+1));
SHM_write_byte(my_shm,byte_to_write);
}
}
DBG_PRINT("RFB_update successful, Shared Memory is filled\n");
}
int SHM_write_byte (char** shm, char byte) {
/*Check if pointer to SHM is valid */
if (shm == (char **) -1) {
/* Pointer is invalid */
return -1;
}
shm = byte;
shm++;
return 0;
}
int main (int argc, char *argv[]) {
if (SHM_init(shmid, my_shm, SHM_KEY, SHM_SIZE) != 0) {
DBG_PRINT("Shared Memory initialized\n");
/* Couldn't initialize SHM,initializing failed */
return -1;
}
/* Initialize RFB Client */
if (RFB_client_init(rfb_client, (FinishedFrameBufferUpdateProc)RFB_update) != 0) {
DBG_PRINT("Couldn't initialize client\n");
/* Couldn't initialize Client,initializing failed */
return -1;
}
--> 到处都使用了变量 "my_shm":内容是:0x00...
今天 whosebug.com 这似乎是一个非常普遍的问题,问题是你将参数 按值 而不是 引用.
这意味着当你将一个参数传递给一个函数时,它的值被复制,并且该函数只在函数内部的本地副本上工作。你应该知道,修改副本当然不会修改原件。
C没有引用传递,但是可以用指针来模拟。在你的例子中,因为你有一个指针,你需要使用地址运算符将指针传递给指针,比如
SHM_init(shmid, &my_shm, SHM_KEY, SHM_SIZE)
// ^
// |
// Note ampersand (address-of operator) here
您当然需要修改函数以实际接受指向指针的指针:
int SHM_init (int shmid, char** shm, key_t key, long int size)
当然在使用变量时使用取消引用运算符*
:
*shm = shmat(shmid, NULL, 0);
我目前正在编写我的学士项目,其中包含一个 RFB 客户端和一个共享内存。 RFB 客户端的初始化已完成,共享内存已创建。我的老师告诉我解耦代码,我写了几个函数并为共享内存使用了一个全局变量。
但是现在在尝试读取全局变量的内容时发生了段错误。我调试了代码,发现:全局变量 "my_shm" 的内容始终为“0x00”:-/ 你能帮帮我吗?
这些是出现问题的代码部分: (我知道,这是一个很长的代码,但是只发送其中的一部分是没有用的...)
char *my_shm; --> //global variable
int SHM_init (int shmid, char* shm, key_t key, long int size) {
/* Create a new (System V) shared memory segment of the specified size */
shmid = shmget(key, SHM_SIZE, IPC_CREAT|0777);
/* Check if SHM creation was successful */
if (shmid < 0) {
/* DBG: Debug message to show which point of the program has been passed */
DBG_PRINT("C\n");
/* Check if creation failed because of already existing SHM */
if (EEXIST == errno) {
/* DBG: Debug message to show which point of the program has been passed */
DBG_PRINT("CC\n");
/* Delete already existing SHM with shmctl */
shmctl(shmid, IPC_RMID, NULL);
} else {
/* DBG: Debug message to show which point of the program has been passed */
DBG_PRINT("CCC\n");
}
/* Creation and initialization of SHM failed */
return -1;
}
/* Attach the SHM data pointer to the previously created SHM segment */
shm = shmat(shmid, NULL, 0);
if(shm == (char *) -1) {
/* Attaching failed */
return -1;
}
DBG_PRINT("Shared Memory Initialization successful\n");
/* Creation and initialization of shared memory was successful */
return 0;
}
void RFB_update(rfbClient* client) {
DBG_PRINT("RFB_update called\n");
int i,j;
rfbPixelFormat* pformat=&client->format;
DBG_PRINT("A\n");
/*bytesPerPix: variable which stores Bytes per Pixel*/
int bytesPerPix = pformat->bitsPerPixel/8;
DBG_PRINT("B\n");
/*row= width of frame*bytes per Pixel*/
int row=client->width*bytesPerPix;
DBG_PRINT("C\n");
char byte_to_write;
//as long as j is smaller than 128*(width*bytesPerPix)
for(j=0;j<client->height*row;j+=row) {
//as long as i is smaller than 128 * bytesPerPix
for(i=0;i<client->width*bytesPerPix;i+=bytesPerPix) {
/*frameBuff: Pointer on FrameBuffer*/
unsigned char* frameBuff = client->frameBuffer+j+i;
unsigned int v;
if(bytesPerPix==4)
v=(unsigned int*)frameBuff;
byte_to_write = ((v>>pformat->redShift)*256/(pformat->redMax+1));
SHM_write_byte(my_shm,byte_to_write);
byte_to_write = ((v>>pformat->greenShift)*256/(pformat->greenMax+1));
SHM_write_byte(my_shm,byte_to_write);
byte_to_write = ((v>>pformat->blueShift)*256/(pformat->blueMax+1));
SHM_write_byte(my_shm,byte_to_write);
}
}
DBG_PRINT("RFB_update successful, Shared Memory is filled\n");
}
int SHM_write_byte (char** shm, char byte) {
/*Check if pointer to SHM is valid */
if (shm == (char **) -1) {
/* Pointer is invalid */
return -1;
}
shm = byte;
shm++;
return 0;
}
int main (int argc, char *argv[]) {
if (SHM_init(shmid, my_shm, SHM_KEY, SHM_SIZE) != 0) {
DBG_PRINT("Shared Memory initialized\n");
/* Couldn't initialize SHM,initializing failed */
return -1;
}
/* Initialize RFB Client */
if (RFB_client_init(rfb_client, (FinishedFrameBufferUpdateProc)RFB_update) != 0) {
DBG_PRINT("Couldn't initialize client\n");
/* Couldn't initialize Client,initializing failed */
return -1;
}
--> 到处都使用了变量 "my_shm":内容是:0x00...
今天 whosebug.com 这似乎是一个非常普遍的问题,问题是你将参数 按值 而不是 引用.
这意味着当你将一个参数传递给一个函数时,它的值被复制,并且该函数只在函数内部的本地副本上工作。你应该知道,修改副本当然不会修改原件。
C没有引用传递,但是可以用指针来模拟。在你的例子中,因为你有一个指针,你需要使用地址运算符将指针传递给指针,比如
SHM_init(shmid, &my_shm, SHM_KEY, SHM_SIZE)
// ^
// |
// Note ampersand (address-of operator) here
您当然需要修改函数以实际接受指向指针的指针:
int SHM_init (int shmid, char** shm, key_t key, long int size)
当然在使用变量时使用取消引用运算符*
:
*shm = shmat(shmid, NULL, 0);