尽管计算每一位,但由 memcpy 引起的分段错误
Segmentation fault caused by memcpy despite counting every bit
我正在尝试使用 memcpy 将数据从字符数组复制到我的 class 的成员中。我在memcpy 之前的调试器write 中设置了一个断点。我检查了我将要使用的所有变量,并计算了目标中还剩下多少 space,看起来它应该可以工作。
#include <iostream>
#include <cstdlib>
#include <cstring>
class bigNum
{
unsigned int dataLength;
unsigned long long int *data;
public:
bigNum(){
//long long int is 8 bytes so (2 * 1024)long long int = 16 KiB
// if that's not enough, we can always add more later
dataLength = 2048;
data = new unsigned long long [dataLength];
};
virtual ~bigNum(){delete[] data;};
//bigNum& operator=(const bigNum& other);
bigNum& set(char chars[], unsigned int charsLength) {
//calculate where we will start writing the data
void *writeStart = (void*)(
(unsigned long long)data + dataLength*64 - charsLength*8
);
//DEBUG -- set a couple of the array elements to watch in debugger
data[2047] = data[2046] = ~((unsigned long long)0);
//zero out the space before writeStart
std::memset(data, 0, dataLength*8 - charsLength);
//write the data starting at writeStart
std::memcpy(writeStart, chars, charsLength);
return *this;
}
};
using namespace std;
int main()
{
bigNum myNum;
char chars[9] = {'a'};
myNum.set(chars, 9);
system("PAUSE");
return 0;
}
错误在此处的语句中:
void *writeStart = (void*)(
(unsigned long long)data + dataLength*64 - charsLength*8
);
也就是说,您似乎正试图以 位 获取正确的写入位置,而您本应以 字节 执行此操作].
当你有像 dataLength*64
和 charsLength*8
这样的语句时,你在 位 中乘以它们的大小,当你正在处理 -指针 - 指的是 字节 .
但是,您似乎对整数大小玩得很随意。 不要那样做! 这意味着您的代码将在其他机器架构上中断。不要假设 unsigned long long
是 64 位,而是找出他们使用 sizeof(unsigned long long)
的确切字节数,或者如果您想要固定宽度的整数,请使用相应的类型,例如 uint64_t
.
然后,对于 C++,您应该坚持使用标准容器,例如 std::vector
。
我正在尝试使用 memcpy 将数据从字符数组复制到我的 class 的成员中。我在memcpy 之前的调试器write 中设置了一个断点。我检查了我将要使用的所有变量,并计算了目标中还剩下多少 space,看起来它应该可以工作。
#include <iostream>
#include <cstdlib>
#include <cstring>
class bigNum
{
unsigned int dataLength;
unsigned long long int *data;
public:
bigNum(){
//long long int is 8 bytes so (2 * 1024)long long int = 16 KiB
// if that's not enough, we can always add more later
dataLength = 2048;
data = new unsigned long long [dataLength];
};
virtual ~bigNum(){delete[] data;};
//bigNum& operator=(const bigNum& other);
bigNum& set(char chars[], unsigned int charsLength) {
//calculate where we will start writing the data
void *writeStart = (void*)(
(unsigned long long)data + dataLength*64 - charsLength*8
);
//DEBUG -- set a couple of the array elements to watch in debugger
data[2047] = data[2046] = ~((unsigned long long)0);
//zero out the space before writeStart
std::memset(data, 0, dataLength*8 - charsLength);
//write the data starting at writeStart
std::memcpy(writeStart, chars, charsLength);
return *this;
}
};
using namespace std;
int main()
{
bigNum myNum;
char chars[9] = {'a'};
myNum.set(chars, 9);
system("PAUSE");
return 0;
}
错误在此处的语句中:
void *writeStart = (void*)(
(unsigned long long)data + dataLength*64 - charsLength*8
);
也就是说,您似乎正试图以 位 获取正确的写入位置,而您本应以 字节 执行此操作].
当你有像 dataLength*64
和 charsLength*8
这样的语句时,你在 位 中乘以它们的大小,当你正在处理 -指针 - 指的是 字节 .
但是,您似乎对整数大小玩得很随意。 不要那样做! 这意味着您的代码将在其他机器架构上中断。不要假设 unsigned long long
是 64 位,而是找出他们使用 sizeof(unsigned long long)
的确切字节数,或者如果您想要固定宽度的整数,请使用相应的类型,例如 uint64_t
.
然后,对于 C++,您应该坚持使用标准容器,例如 std::vector
。