2

我在使用该memcpy功能时遇到问题。我需要一个将数据存储到void指针中的函数。这是一个简单的例子:

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

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

谢谢,麻烦您了。

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

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 个字符分配了足够的空间,整个字符串也会被复制。那不应该给我一个错误吗?

4

4 回答 4

4

您的函数参数data需要指向有可用内存的地方。你可以这样做:

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

如果您更喜欢使用mallocand free,那么您的代码将更像这样:

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

..这两者的问题在于您不知道字符串需要多长时间。使用 std::string 会更安全/更容易。

std::string myString;  // an empty string
myString += "some data"; // append a string
于 2013-06-03T23:18:11.203 回答
2

请注意,源的大小不是由 strlen 给出的,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;
}
于 2013-06-03T23:23:35.847 回答
1

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

用于malloc分配一块内存以从中复制inputData

于 2013-06-03T23:12:50.220 回答
1

如果您不提前知道数据的大小,那么让它工作的唯一方法是 malloc 一些任意大的缓冲区,并确保您永远不会将超过 # 的字节复制到 void* 中。不是最好的设计,但它会起作用。

另外,不要忘记为字符串末尾的 NULL 字符分配一个额外的字节,并且不要忘记实际将 null 放在内存缓冲区的末尾。在上面的示例中,您的字符串 indata最后不会有 NULL。

于 2013-06-03T23:17:46.987 回答