【问题标题】:Attempt to dereference a generic pointer.尝试取消引用通用指针。
【发布时间】:2016-04-16 04:41:41
【问题描述】:

我正在尝试直接使用一些低级内存的东西。我正在用一些数据填充缓冲区,然后将其复制到更大的缓冲区。

我写了这个函数来帮助处理一些浮点数据:

void copy_float_buffer(void* dest, size_t dest_index, void* src,
                       size_t src_index, size_t num_to_copy) {
    memcpy(&dest[dest_index], &src[src_index], num_to_copy * sizeof(float));
}

我目前有两个不同的缓冲区,每种类型两个。

float buffa[12]; // i have two of these
float buffb[12]; // and two of these as well

然后有两个更大的缓冲区将这些缓冲区背靠背。 浮动缓冲区[24]; //拥有2个buffa float bufferb[24] //持有2个buffb

我有一个简单的 for 循环,它会进行一些计算并填充 buffa 和 buffb,然后我使用 copy_float_buffers 命令来填充缓冲区。我就是这样做的。

typedef struct {
    float buffa[12];
    float buffb[12];
} buffs;
buffs* b;
for (int j = 0; j < 2; j++) {
    b = calloc(1, sizeof(buffs));
}

for (int i = 0; i < 12; i++) {
    b->buffa[i] = vmathRandRange(21);
    b->buffb[i] = vmathRandRange(21);
}
for (int i = 0; i < 12; i++) {
    /* printf("index:%d value:%f \n", i, b->buffa[i]); */
    /* b->buffa[i] = vmathRandRange(21); */
    copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffa,
                      (sizeof(float) * i) * 12, 12);
    copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffb,
                      (sizeof(float) * i) * 12, 12);
}
print_buffer(b->buffa, "original buffer");
print_buffer(v_buff, "vertex buffer");
print_buffer(b->buffb, "original buffer");
print_buffer2(v_buff, "vertex buffer");

print_buffers 函数只循环 0-11 或 12-22 并打印出值。

我觉得这是一个指针数学问题,我正在使用 gdb 尝试查看代码并查看它是如何被复制的,但我得到了上面的错误。

Attempt to dereference a generic pointer. 

在单步执行 gdb 中的代码时如何取消引用指针以及。我认为执行内存复制的功能设置正确。但它似乎只是覆盖了前 12 个浮点数或前 48 个字节,并没有真正移位,类似于环形缓冲区。

【问题讨论】:

  • dest[dest_index] 无效,因为void 没有大小。为什么不是float*之类的?
  • 您不能取消引用 generic pointer
  • 如果calloc分配了内部包含两个缓冲区的struct,为什么还要调用两次?另外,请注意您替换了循环中的最后一个calloc 结果,导致内存泄漏。 copy_float_buffer 已经填满了缓冲区的 12 个位置,为什么要在 0 到 12 的范围内调用它?此外,它在相同的目的地被调用两次,覆盖第一次调用。
  • calloc(1, sizeof(buffs)) 询问指针的大小,而不是它将指向的 struct

标签: c debugging pointers segmentation-fault gdb


【解决方案1】:

正如在 cmets 中已经提到的,你不能仅仅因为 destvoid* 而做 dest[dest_index]

您的复制功能似乎很奇怪。在主代码中,您花费了大量精力来计算字节偏移量,但您仍然在 copy_float_buffer 函数中使用 sizeof(float)。您应该编写函数以在任何地方使用浮点数或在任何地方使用字节 - 这将更容易理解。

由于函数调用copy_float_buffer,表示你要复制浮点数,所以应该是:

void copy_float_buffer(float* dest, size_t dest_index, float* src,
                       size_t src_index, size_t num_to_copy) {
    memcpy(&dest[dest_index], &src[src_index], num_to_copy * sizeof(float));
}

复制num_to_copy 浮动。如果您这样做,则需要更改调用函数的方式,即摆脱所有字节偏移量计算。比如:

    copy_float_buffer(v_buff, 0, b->buffa, 0, 12);  // Ends in v_buff[0..11]
                              ^            ^   ^
                              |            |   Copy 12 floats
                              |            Start offset in buffa
                              Start offset in v_buff

    copy_float_buffer(v_buff, 12, b->buffb, 0, 12); // Ends in v_buff[12..23]
                              ^             ^   ^
                              |             |   Copy 12 floats
                              |             Start offset in buffb
                              Start offset in v_buff

你的其余代码也有一些问题:

// You loop twice but simply overwrite `b` the second time
// so you leak memory
for (int j = 0; j < 2; j++) {
    b = calloc(1, sizeof(buffs));
}

// Why do you loop 12 times?
// Do you want to copy the data in to the main buffer 12 times?
for (int i = 0; i < 12; i++) {
    // The two call of copy_float_buffer is identical except for buffa and buffb
    // So buffb will overwrite buffa
    // Probably not what you want or ...?
    copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffa,
                      (sizeof(float) * i) * 12, 12);
    copy_float_buffer(v_buff, (sizeof(float) * i) * 12, b->buffb,
                      (sizeof(float) * i) * 12, 12);
}

【讨论】:

  • 这两个循环是错字,第二个循环。还有第二个循环你是对的。我正在覆盖数据,最初我想分 12 步复制数据,一次一个。
猜你喜欢
  • 2013-12-23
  • 2013-02-21
  • 2013-01-08
  • 2013-08-21
  • 2018-02-14
  • 2020-06-05
  • 1970-01-01
  • 2012-07-06
相关资源
最近更新 更多