2014-01-29 1 views
1

Я хочу использовать memcpy, чтобы скопировать строку в указатель на пустоту (причина, по которой я копирую указатель void, заключается в том, что в моем фактическом приложении я мог бы копировать множество типов, так что я пытаюсь быть вообще), но используя немного кода примера ниже, я столкнулся с проблемой:Проблемы с использованием memcpy для копирования из строки в указатель void

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int main(void){ 
    char *str1 = strdup("Hello"); 

    void *str2 = malloc(strlen(str1)+1); 

    fprintf(stdout, "str1 = %s\n", str1); 

    memcpy(str2, str1, strlen(str1)+1); 

    fprintf(stderr, "str2 = %s\n", *(char **)str2); 

    free(str1); 

    fprintf(stderr, "str2 = %s\n", *(char **)str2); 

    return 0; 
} 

в этом примере я получаю Segmentation Fault при попытке распечатать str2. Кто-нибудь знает, почему это не работает? Это проблема с литью указателя void на char или что-то более фундаментальное с memcpy? Однако, если я изменю линию memcpy на memcpy(str2, &str1, strlen(str1)+1), я могу распечатать str2 до освобождения str1, но после освобождения str1str2 также исчез.

Я знаю, что это будет все работать, если я объявляю str2 с char*, а не void* (и удалить отливку в отчетности вывода на печать), но я хотел бы избежать этого, если это возможно.

Обновление: Я изменил код примера, чтобы избежать первоначальной утечки памяти.

+0

Ваш трюк неверен. Вы не хотите '* (char **)', вы просто хотите '(char *)'. – Kevin

+2

Кроме того, ваш первоначальный 'malloc' - это не что иное, как утечка памяти,' strdup' выделяет собственную память. – Kevin

+2

@ Кевин может захотеть поставить это в ответ, так как он действительно отвечает на его вопрос. – Avery3R

ответ

3

Ваш трюк неверен. Вы не хотите *(char **), вы просто хотите (char *), и даже это не нужно.

Кроме того, ваш начальный malloc - это не что иное, как утечка памяти, strdup выделяет собственную память.

+0

Спасибо, что решает мою проблему точно. В моем фактическом приложении мне нужно выполнить кастинг '(char *)', поскольку он является частью базы кода, где компиляция выполняется со строгими флагами, которые обрабатывают любые предупреждения (которые не используют кастинг) в качестве ошибок. –