Выделение динамической памяти внутри функции - C (СИ)

Узнай цену своей работы

Формулировка задачи:

приветствую. Изучаю С, для лушчего усвоения изобретаю велосипед - попылатся реализовать собственный вариант strcpy с использованием динамической памяти. Вот что вышло:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void mystrcp(char *, char *, int );
//int mystrlen(char *, int );
int main()
{
    char *str= "Hello World", *str2 ;
    int len;
    len = strlen(str);
    mystrcp(&(*str),&(*str2), len);
    free(str2);
    return 0;
}
void mystrcp(char *str, char *str2, int len )
{
    if(NULL == (str2=malloc(len+1)))
    {
        printf("ERROR\n");
        exit(1);
    }
    for(int i=0;i<=len;i++)
        *(str2+i) = *(str+i);
}
не работает. почему совершенно не могу разобраться. В данном случаем программа компилируется нормально, но при запуске вывод:
bash-4.2$ ./srt
UWVS�i
*** glibc detected *** ./srt: double free or corruption (out): 0x08048530 ***
======= Backtrace: =========
/lib/libc.so.6[0x4e4842b5]
./srt[0x80484b0]
/lib/libc.so.6(__libc_start_main+0xf3)[0x4e42c413]
./srt[0x80483b1]
======= Memory map: ========
00c56000-00c57000 r-xp 00000000 00:00 0          [vdso]
08048000-08049000 r-xp 00000000 08:12 9306235    /home/obtical/sources/c/srt
08049000-0804a000 rw-p 00000000 08:12 9306235    /home/obtical/sources/c/srt
09fa5000-09fc6000 rw-p 00000000 00:00 0          [heap]
4e3f2000-4e40f000 r-xp 00000000 08:01 1972       /lib/ld-2.14.so
4e40f000-4e410000 r--p 0001d000 08:01 1972       /lib/ld-2.14.so
4e410000-4e411000 rw-p 0001e000 08:01 1972       /lib/ld-2.14.so
4e413000-4e598000 r-xp 00000000 08:01 2921       /lib/libc-2.14.so
4e598000-4e59a000 r--p 00184000 08:01 2921       /lib/libc-2.14.so
4e59a000-4e59b000 rw-p 00186000 08:01 2921       /lib/libc-2.14.so
4e59b000-4e59e000 rw-p 00000000 00:00 0 
4e5fa000-4e616000 r-xp 00000000 08:01 7392       /lib/libgcc_s-4.6.0-20110530.so.1
4e616000-4e617000 rw-p 0001b000 08:01 7392       /lib/libgcc_s-4.6.0-20110530.so.1
b7835000-b7836000 rw-p 00000000 00:00 0 
b7847000-b784a000 rw-p 00000000 00:00 0 
bffa6000-bffc7000 rw-p 00000000 00:00 0          [stack]
Аварийный останов (core dumped)
если убрать free(str2), то ошибки никакой не происходит, но вместо строки выводится мусор.
bash-4.2$ ./srt
UWVS�i
если же попытаться вывывести содержимое str2 внутри функции mystrcp(), то никаких проблем нет и печатается строка. прошу помочь разобраться в чем проблема, ведь при завершении работы ф-ции память освобождаться не должна, а адрес тот же... заранее спасибо.

Решение задачи: «Выделение динамической памяти внутри функции»

textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void mystrcp(char *, char *, int );
//int mystrlen(char *, int );
int main()
{
        char *str= "Hello World", *str2 ;
        int len;
        len = strlen(str);
        str2=(char*)malloc(sizeof(char) * len + 1);
        mystrcp(str,str2, len);
        puts(str2);
        free(str2);
        return 0;
}
 
void mystrcp(char *str, char *str2, int len )
{
  int i;
  for(i=0;i< len;i++)
    str2[i] = str[i];
  str2[i] = '\0';
}

Объяснение кода листинга программы

  1. #include — подключает файл стандартного ввода/вывода, что позволяет использовать функции для работы с консолью, такие как printf и puts
  2. #include — подключает файл stdlib.h, который содержит функции для работы с памятью, такие как malloc и free
  3. #include — подключает файл string.h, который содержит функции для работы со строками, такие как strlen и strcpy
  4. void mystrcp(char , char , int ); — объявление функции mystrcp, которая принимает три аргумента типа char* и int, и возвращает void (ничего не возвращает)
  5. int main() — объявление функции main, которая является точкой входа в программу и возвращает int (код возврата)
  6. char str= Hello World, str2 ; — объявление двух указателей на char, str и str2, и инициализация их значений строкой Hello World
  7. len = strlen(str); — вычисление длины строки с помощью функции strlen и сохранение результата в переменной len
  8. str2=(char)malloc(sizeof(char) len + 1); — выделение динамической памяти с помощью функции malloc для хранения строки str2, размер памяти равен len + 1 (так как нужна память для символа '\0' в конце строки)
  9. mystrcp(str,str2, len); — вызов функции mystrcp, передача ей аргументов str, str2 и len
  10. puts(str2); — вывод строки str2 на консоль с помощью функции puts
  11. free(str2); — освобождение выделенной памяти с помощью функции free
  12. return 0; — возврат значения 0 из функции main, что означает успешный конец работы программы
  13. void mystrcp(char str, char str2, int len ) — определение функции mystrcp
  14. int i; — объявление переменной i типа int, которая будет использоваться в цикле for
  15. for(i=0;i< len;i++) — начало цикла for, который будет выполняться, пока значение i меньше len
  16. str2[i] = str[i]; — копирование символа из строки str в строку str2 с помощью оператора присваивания
  17. str2[i] = '\0'; — добавление символа '\0' в конец строки str2, чтобы обозначить конец строки
  18. return; — возврат из функции mystrcp без возвращения значения
  19. *char str= Hello World;* — определение переменной str типа char и инициализация ее значением Hello World
  20. *char str2;* — определение переменной str2 типа char и инициализация ее значением пустой строкой (предполагается, что в памяти уже выделена достаточная область для хранения строки)

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.2 из 5
Похожие ответы