Вызов strcpy для char* дважды
Хочу спросить у вас об одной проблеме, внятного объяснения которой я не смог найти.
Проблема вот в чем:
создаются 3 указателя на char:
Затем происходит копирование из st1 в st2:
Здесь все проходит хорошо, но
Если же сделать указатели массивами или выделить динамически под них память все проходит как по маслу.
Я сделал альтернативу strcpy:
{
for(int i=0; (out=in)!='\0';i++);
}
но ничего не изменилось.
Я понимаю различия между char* и char [], но тем не менее не могу понять, где собака зарыта. :confused:
Почему в первый раз вызывается нормально, а во второй вылетает?
Почему именно с ошибкой запрета доступа к памяти?
Объясните пожалуйста в чем здесь проблема. :confused:
P.S. Использовался компилятор Builder C++ 6.0, если это имеет значение
Это частный случай, в общем случае - это грубейшая ошибка.
Я сделал альтернативу strcpy:
{
for(int i=0; (out=in)!='\0';i++);
}
но ничего не изменилось.
Не верю. Наверняка на эту альтернативу уже компилятор ругался, а не программа вылетала.
А чего ему ругаться?
Кстати, можно было сделать функцию на основе классического примера:
{
while(*out++ = *in++);
}
Происходит обращение к элементам массивов (in, out), которые не были объявлены.
(Изменил ответ, так как ранее он был грубоват и не ясен)
#include <string.h>
#include <malloc.h>
int main()
{
char * st1="text", *st2, *st3;
// выделяем память
st2=malloc(strlen(st1)+1);
st3=malloc(strlen(st1)+1);
// копируем строки
strcpy(st2,st1);
strcpy(st3,st1);
// выводим строки
printf("%s\n%s\n%s\n", st1, st2, st3);
// освобождаем память
free(st2);
free(st3);
// конец
return 0;
}
З.Ы. При работе со строками в Билдере обычно используют класс AnsiString. В этом случае память выделяется и освобождается автоматически.
З.Ы. При работе со строками в Билдере обычно используют класс AnsiString. В этом случае память выделяется и освобождается автоматически.
При работе со строками на C++ обычно используют класс std::string.
char *strdup(const char *).
malloc() и strcpy() в одном флаконе.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int main()
{
char * st1="text", *st2, *st3;
st2=strdup(st1);
st3=strdup(st1);
// выводим строки
printf("%s\n%s\n%s\n", st1, st2, st3);
// освобождаем память
free(st2);
free(st3);
// конец
return 0;
}
(Изменил ответ, так как ранее он был грубоват и не ясен)
Смотрим стандарт:
5.2.1 Subscripting [expr.sub]
1 A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “pointer to T” and the other shall have enumeration or integral type. The result is an lvalue of type “T.” The type “T” shall be a completely-defined object type.56) The expression E1[E2] is identical (by definition) to *((E1)+(E2)). [Note: see 5.3 and 5.7 for details of * and + and 8.3.4 for details of arrays. ]
Извиняюсь. Ошибался. Привык к использованию адресной арифметики при работе с указателями.
[QUOTE=Ден Зурин]При работе со строками в Билдере обычно используют класс AnsiString. В этом случае память выделяется и освобождается автоматически.[/QUOTE]
[QUOTE=Green]При работе со строками на C++ обычно используют класс std::string.[/QUOTE]
Спасибо за совет, но мне нужно обрабатывать строки именно таким примитивным образом - через char* :)
[QUOTE=Trilobit]
char *strdup(const char *)
[/QUOTE]
Спаисбо, приму к сведению :)
[QUOTE=Kogrom]Не верю. Наверняка на эту альтернативу уже компилятор ругался, а не программа вылетала.[/QUOTE]
Уж поверь - мне врать ни к чему :)
Да ничего потом не закрывается - сказали же, это частный случай.
Просто первый раз не сделало ничего критического, чтобы сразу порушить программу, или сделала но это не обнаружилось сразу. А второй раз уже обнаружилось.
Просто запомни, что так делать нельзя - что то писать по неизвестно куда указываемому указателю.