0

我有一个这样分配的结构:

static struct cparray_buffer_t *_cparray;

struct __attribute__ ((__packed__)) cparray_buffer_t 
{
    u_int64_t buflen;
    u_char buf[buffersize];
}

.
.
.
_cparray = (struct cparray_buffer_t *)calloc(1024, sizeof(struct cparray_buffer_t);

后来在程序中,我尝试像这样做一个 memcpy

memcpy(_cparray[0].buf, test, buffersize);

我得到一个 sigsegv

我在 memcpy 中正确地引用了吗?

编辑:在 gdb 中,当实际使用数组时,_cparray 的地址似乎是 0x0。我试图在 _cparray 上放置一个数据观察点,但没有看到任何释放它的东西。有趣的是,如果我看一下 &_cparray 它仍然有一个有效的地址,但是 *&_cparray 是 0x0

edit2:不知道是否有区别,但是calloc在thread1中,而segfault在thread2中发生。我的印象是全局静态对所有线程都是可见的。这个对吗?

谢谢

到底是怎么回事?

这是 _cparray 上的观察点的输出

Old value = (struct cparray_buffer_t *) 0x284ba000
New value = (struct cparray_buffer_t *) 0x0
0x28102c83 in sem_init () from /lib/libc.so.7
4

1 回答 1

0

全局变量在所有线程中都是可见的,无论是否是静态的。static 关键字只是给出变量文件范围,以便它只在文件中可见。由于它仅在文件中可见,因此使用该变量的代码必须在定义它的文件中。

我看到的一个问题是人们将静态变量放入头文件中,期望该变量对多个文件可见。结果是静态变量在每个包含头文件的文件中重复,导致静态变量的几个不同实例在各个文件之间没有共享,因为它们是不同的内存位置。

由于这是一个多线程应用程序,其中一个线程创建内存区域,第二个线程使用内存区域,您可能会遇到竞争条件,即第二个线程在第一个线程分配内存区域之前正在访问它。

例如,我首先将指针初始化为已知值

static struct cparray_buffer_t *_cparray = 0;

然后,在第二个线程中,您可以测试变量是否具有一个检查 0 的地址,如果它为零,则休眠并重试,直到它变为非零,这意味着第一个线程已分配内存。首选方法是让第一个线程分配内存,然后启动第二个线程以使用内存。或者,您可以使用其他线程同步,只要第二个线程等到第一个线程在尝试使用指针之前分配内存。

假设 test 是某种类型的指针,例如数组,那么 memcpy() 函数调用看起来是正确的。我假设代码看起来像:

u_char test[buffersize];
// do some things involving test

// save the things put into test
memcpy (_cparray[0].buf, test, buffersize);
于 2012-08-09T03:08:48.367 回答