Выделение динамической памяти внутри функции - C (СИ)
Формулировка задачи:
приветствую. Изучаю С, для лушчего усвоения изобретаю велосипед - попылатся реализовать собственный вариант strcpy с использованием динамической памяти. Вот что вышло:
не работает. почему совершенно не могу разобраться. В данном случаем программа компилируется нормально, но при запуске вывод:
если убрать free(str2), то ошибки никакой не происходит, но вместо строки выводится мусор.
если же попытаться вывывести содержимое str2 внутри функции mystrcp(), то никаких проблем нет и печатается строка.
прошу помочь разобраться в чем проблема, ведь при завершении работы ф-ции память освобождаться не должна, а адрес тот же... заранее спасибо.
#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)
bash-4.2$ ./srt UWVS�i
Решение задачи: «Выделение динамической памяти внутри функции»
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'; }
Объяснение кода листинга программы
- #include
— подключает файл стандартного ввода/вывода, что позволяет использовать функции для работы с консолью, такие как printf и puts - #include
— подключает файл stdlib.h, который содержит функции для работы с памятью, такие как malloc и free - #include
— подключает файл string.h, который содержит функции для работы со строками, такие как strlen и strcpy - void mystrcp(char , char , int ); — объявление функции mystrcp, которая принимает три аргумента типа char* и int, и возвращает void (ничего не возвращает)
- int main() — объявление функции main, которая является точкой входа в программу и возвращает int (код возврата)
- char str=
Hello World
, str2 ; — объявление двух указателей на char, str и str2, и инициализация их значений строкойHello World
- len = strlen(str); — вычисление длины строки с помощью функции strlen и сохранение результата в переменной len
- str2=(char)malloc(sizeof(char) len + 1); — выделение динамической памяти с помощью функции malloc для хранения строки str2, размер памяти равен len + 1 (так как нужна память для символа '\0' в конце строки)
- mystrcp(str,str2, len); — вызов функции mystrcp, передача ей аргументов str, str2 и len
- puts(str2); — вывод строки str2 на консоль с помощью функции puts
- free(str2); — освобождение выделенной памяти с помощью функции free
- return 0; — возврат значения 0 из функции main, что означает успешный конец работы программы
- void mystrcp(char str, char str2, int len ) — определение функции mystrcp
- int i; — объявление переменной i типа int, которая будет использоваться в цикле for
- for(i=0;i< len;i++) — начало цикла for, который будет выполняться, пока значение i меньше len
- str2[i] = str[i]; — копирование символа из строки str в строку str2 с помощью оператора присваивания
- str2[i] = '\0'; — добавление символа '\0' в конец строки str2, чтобы обозначить конец строки
- return; — возврат из функции mystrcp без возвращения значения
- *char str=
Hello World
;* — определение переменной str типа char и инициализация ее значениемHello World
- *char str2;* — определение переменной str2 типа char и инициализация ее значением пустой строкой (предполагается, что в памяти уже выделена достаточная область для хранения строки)
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д