2013-06-03 37 views
2

我遇到memcpy函数有问题。我需要一个将数据存储到void指针的函数。这里有一个简单的例子:带空指针的Memcpy

void saveData(void* data) 
{ 
    char inputData[] = "some data"; 
    memcpy((char*)data, inputData, sizeof(inputData)); 
} 

但是,当我这样做,即使它编译得很好,我得到分割错误。我的函数参数必须是一个无效指针,因为我可能有不同的数据格式输入,我可能不会提前知道数据的大小。有人能告诉我我做错了什么吗?

请谢谢。

** UPDATE: 感谢所有的有用的反应。正如大多数人指出的那样,我没有初始化void数据。这解决了它。 现在我的问题是:当我为void *数据(甚至char *数据)进行动态分配时,我给它一个大小,但是当我做memcpy时,它允许我写一个比我第一次分配空间更大的字符串对于。我也试着只是在做char *数据,并且发生同样的事情。这是我的示例代码:

char inputData[] = "123456789"; 
void* data1 = malloc(5*sizeof(char)); 
char* data2 = (char*)malloc(5*sizeof(char)); 

memcpy(data1,inputData,sizeof(inputData)); 
memcpy(data2,inputData,sizeof(inputData)); 

当我打印出来的结果,inputData的整个字符串被复制,即使我只为5个字符分配足够的空间。这不应该给我一个错误?

+9

显示来电,这就是问题的所在。它传递给你一个你无法通过的指针。 – Barmar

+0

你'malloc()'有足够的内存来存储'数据'吗? – SpacedMonkey

+0

分段错误,在这种情况下,意味着'数据'可能小于文本数据的大小。从外观上看,它应该至少有10个字节 – tay10r

回答

4

您的功能参数data需要指向某处有可用内存。 你可以做这样的事情:如果你喜欢使用mallocfree

int main() 
{ 
    char myString[256]; 
    saveData((void*)myString); 
} 

,那么你的代码会更喜欢这样的:

int main() 
{ 
    char* myString = (char*)malloc(256); 
    saveData((void*)myString); 
    free(myString); 
} 

与这两个..the麻烦的是,你不知道字符串需要多长时间。使用std :: string会更安全/更简单。

std::string myString; // an empty string 
myString += "some data"; // append a string 
+2

问题用'C'标记,所以我假设'std :: string'超出了范围。但这个答案的其余部分看起来不错。 – tom

1

data需要指向您有权访问的地方。您无法访问的空指针区域(除非您正在运行DOS或其他东西)。

使用malloc分配的内存块复制从inputData到。

1

如果你不知道的时间提前数据的大小,得到这个工作的唯一办法就是malloc的一些任意大小的缓冲区,并确保今后不再复制比#字节的多进空* 。不是最好的设计,但它会起作用。

另外,不要忘记为在字符串结尾的NULL字符分配一个额外的字节,并且不要忘记居然把空的内存缓冲区的末尾。在上面的例子中,data中的字符串最后不会有NULL。

2

注意源的大小不是由sizeof但strlen的给出。假设调用者不想分配内存,则需要存储malloc并且有void *存储句柄。鉴于保存函数调用malloc,我会设置一个相应的释放函数。

bool saveData(void** retSave, const char* input) 
{ 
    bool success = false; 
    size_t storageSize = strlen(input) + 1; 
    void* store = malloc(storageSize); 
    if (store) 
    { 
     memcpy(store, input, storageSize); 
     success = true; 
    } 
    return success; 
} 



void releaseSavedData(void* savedData) 
{ 
    free(savedData); 
} 

int main() 
{ 
    void* saveHandle = 0; 
    bool ok = saveData(&saveHandle, "some data"); 
    if (ok) 
    { 
     releaseSavedData(saveHandle); 
    } 
    return 0; 
}