Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Использование "раздельних" указателей / 22 сообщений из 22, страница 1 из 1
10.03.2017, 15:04
    #39416978
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Есть у меня пример имплементации функции strcat:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
char *strcat(char *dest, const char *src)
{
    char *ret = dest;
    while (*dest)
        dest++;
    while (*dest++ = *src++)
        ;
    return ret;
}



Сперва указатель ret указывает на второй указатель (строку) dest; То есть например *dest="абв" и *ret="где".
Потом указатель дест оказывается на последнем символе (байте). Вроде указатель dest оказывается на нуль-символе и дальше продолжатся не может. Однако начинается другой цыкл и он уже указывает на начало третьего указателя (второго масива символов) или присваивает уже значение следующим байтам (которые больше его длины) занчение сначала второй строки которая находится совсем в другой области памяти??? Как такое может быть -- может здесь надо варианты while (*rest++ = *src++) или (dest++ = src++)? Как возмиожно такое перескакивание? Проверить не могу -- выскакивает Segmentation Fault (Core Dumped), но хоть такой подход для реализации такой функции стандартный, много отзывов что это и не будет работать.
...
Рейтинг: 0 / 0
10.03.2017, 15:17
    #39416990
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrt,

Эта реализация правильная.
Чтобы она работала, так же как и для стандартной strcat, первый указатель должен указывать на буфер способный вместить обе строки и завершающий ноль.
И тогда не будет сегфолта )))
...
Рейтинг: 0 / 0
10.03.2017, 15:24
    #39417000
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Вот есть имплементация второй функции которая есть второй частью вышеприведенной функцииЖ
char *strcpy(char *dest, const char *src)
{
char *save = dest;
while(*dest++ = *src++);
return save;
}
Здесь тоже идет присваивание указателя --
Наверное возможно и сразу написать while(*dest++ = *src++) -- но такой вариант ка-бы заблаговременно констатирует равность одних и тех же указателей. Одно -- дело когда они совпадают, но а если -- они находятся в разных областях памяти.
...
Рейтинг: 0 / 0
10.03.2017, 15:26
    #39417005
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Первый указатель должен указывать на буфер способный вместить обе строки и завершающий ноль.
И тогда не будет сегфолта ))) -- для чего такая имплементация приведена если она неполная -- где полная?
Касательно буфера -- он же там есть -- там три переменных указателя.
...
Рейтинг: 0 / 0
10.03.2017, 15:30
    #39417015
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrt- для чего такая имплементация приведена если она неполная -- где полная?
Касательно буфера -- он же там есть -- там три переменных указателя.
Это полная реализация.
Просто вы неправильно вызываете функцию.
Приведите вызывающий код и будет видно что не так.
...
Рейтинг: 0 / 0
10.03.2017, 15:32
    #39417020
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Вот еще один вариант -- с вызовом.
#include <stdio.h>
char *strcat(char *dest, const char *src)
{
size_t i,j;
for (i = 0; dest[i] != '\0'; i++)
;
for (j = 0; src[j] != '\0'; j++)
dest[i+j] = src[j];
dest[i+j] = '\0';
return dest;
}

int main()
{
char*s1="abc",*s2="def";

printf("%s",strcat(s1,s2));
}
...
Рейтинг: 0 / 0
10.03.2017, 15:41
    #39417034
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrtchar*s1="abc",*s2="def";
s1 указывает на константную память "abc" (4 байта)
Функция strcat должна выполнять дополнение первого аргумента вторым.
В вашем случае не только размер первого аргумента не достаточен, но и память недоступна для записи.
...
Рейтинг: 0 / 0
10.03.2017, 15:50
    #39417043
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Как сделать правильно? Я этот пример не выдумал -- в нете не один такой.
Вопрос в том тоже -- как же указатель дест разсширяется при помощи другого указателя, в тоже время когда йункция возращает третий.
...
Рейтинг: 0 / 0
10.03.2017, 15:54
    #39417046
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
memmove memcpy копирует байты (память), а как же тогда указатели скачут по разным областям памяти непонятно.
...
Рейтинг: 0 / 0
10.03.2017, 16:27
    #39417071
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrtВопрос в том тоже -- как же указатель дест разсширяется при помощи другого указателя
Он не расширяется.
Указатель указывает на позицию в буфере. Сам указатель можно произвольно сдвигать куда нужно согласно алгоритма, но буфер при этом не расширяется. О буфере вы должны отдельно побеспокоиться.
Читайте про работу с указателями. Вы пока не понимаете что это. А мне некогда объяснять.

Вот пример корректного вызова.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
int main()
{
  char*s1="abc",*s2="def";
  char*s3 = malloc(strlen(s1) + strlen(s2) + 1);
  strcpy(s3, s1);
  strcat(s3, s2);
  printf("%s", s3);
} 
...
Рейтинг: 0 / 0
16.03.2017, 03:04
    #39420414
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Приведите мне этот буфер -- нужно ли знать его размер заблаговременно? Включает ли он последовательные ячейки памяти -- или он работает по принципу -- что он заполняется сплошной областю памяти, если надо перескочить на другую область памяти тогда он освобождается, и заполняется другими последовательными ячейками памяти.
Например касательно неопределенного количества символов -- например для функции замены одного символа двумя, тремя и т.д. если неизвестно количсетво заменяемого символа в строке? Это задание выполнимо с помощью указателей а если надо заменить слова в предложение на обратный порядок (слово1 слово2 слово3)=>(слово3 слово2 слово1) -- применимы ли здесь указатели? Что здесь будет с буфером, или здесь вообще просто посколько известна или можно определить длину строки. То есть идет указатель с конца исходной строки до пробела, делает какой то маркер и во вложенном цыкле идет в обратном порядке заполняя первое слово, и при натыкание на пробел происходит выход из цыкла, и уже внешний указатель продолжает проход по предпоследнему слову и т.д. Это спрашиваю ибо использовал масив символом, хотя кажется что указатели здесь как раз кстати, не надо считать количсество букв в отдельном слове.
...
Рейтинг: 0 / 0
16.03.2017, 04:31
    #39420420
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrt,
вот набросок разворота слов в предложение (так к общей теме указателей):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
#include <stdio.h>
char *strcat(const char *src)
{
//char *src1;
//src1=src;
char *dest;
int l;
while (*src) l++;
while (--src)        {
                     if(*src==' ') {
        const char* temp;
        temp=src;
        while(*temp) {
        *dest=*temp;
        temp++;
        }
                     *dest=' ';}
        *(++dest)='.'; } 
        return dest;
}


Возвращает "ничего", компилится без ошибок.
Очевидно надо возвратит dest в начало результирующей строки.
...
Рейтинг: 0 / 0
16.03.2017, 09:49
    #39420500
ermak.nn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Извините, но вы рветесь в бой с автоматом Калашникова, кричите, что всех убьете, но при этом стрелять не умеете.
Советую сначала почитать про выделение памяти и разницу между:
Код: plaintext
1.
char* c  = "abc";


и
Код: plaintext
1.
2.
3.
int size = 4;
char* c = (char*) malloc(size);
strncpy(c, "abc", size);



Также, советую почитать про calloc, realloc, free, new, delete, new[], delete[]
...
Рейтинг: 0 / 0
19.03.2017, 02:14
    #39422371
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
ermak.nn,
Читать -- читали.
Если вы имеете ввиду что под указатель обязательно надо
выделять память -- то это понятною
Хотя из вышеприведеного кода, в начале, как-бы не следует это.
...
Рейтинг: 0 / 0
19.03.2017, 08:53
    #39422391
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Подразумевается, что память правильно выделена вызывающей функцией.

И еще - "=" это присваивание, возвращающее результат, а сравнение на равенство пишется так "==" (и возвращает логический результат 0 или не ноль)
...
Рейтинг: 0 / 0
20.03.2017, 16:38
    #39423373
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Говорить о разнице "=" и "==" это конечно интересно.
Что значит память выделяется вызывающей функцией?
Первый код в этой теме встречается сплош и рядом -- если надо еще какой то буфер, выделение память для чего морочить голову таким упрощенными вариантами.
Насколько помню -- указатель указывает на ячейку памяти (динамической кучи), если после первого символа надо заполнить следующую ячейку, то вроде выделять не надо -- хотя если следующая ячейка памяти занята уже -- то это уже иная проблема.
...
Рейтинг: 0 / 0
20.03.2017, 16:47
    #39423385
Siemargl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrt,

это клиника. иди читай учебники для самых маленьких
...
Рейтинг: 0 / 0
21.03.2017, 09:09
    #39423748
ermak.nn
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
Вы уверены, что вам нужен C или C++? Мне кажется, что нет, т.к. вы не понимаете, что за работу с памятью отвечает программист, и если он говорит программе выстрелить в ногу, она выстрелит. Вы этим и занимаетесь, хотя утверждаете, что "читали" про язык.
Может всё-таки начать хотя бы с "Язык программирования Си" Брайан Керниган, Деннис Ритчи? Если нет, то увы.
Конечно, можно попробовать изучить программирование наскоком, с кучей непонятных никому вопросов, но что-то хорошего из этого не получится.
...
Рейтинг: 0 / 0
08.04.2017, 12:40
    #39435167
arrt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
все таки спрошу -- что такое абсурдное, что я здесь написал?
Что под любой указатель надо выделять память, даже под char*, в любом случае?
Я с С/C++ сталкиваюсь так раз в полгода, так что не надо утрировать.
...
Рейтинг: 0 / 0
08.04.2017, 13:24
    #39435178
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrtвсе таки спрошу -- что такое абсурдное, что я здесь написал?
Код: plaintext
1.
while (*src) l++; // Бесконечный цикл


Код: plaintext
1.
2.
3.
4.
char *dest;
while (--src)        { // Куда -- ?
..
        *dest=*temp; // Запись в память по случайному адресу


Это только то что в глаза бросилось. Дальше не стал вникать. Сомневаюсь на счет:
arrtВозвращает "ничего", компилится без ошибок.
...
Рейтинг: 0 / 0
08.04.2017, 19:20
    #39435240
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrt, эта функция, как и большинство в языке "C" - опасная.
И перед тем как ее использовать надо озаботиться достаточным
объёмом буфера для dest.

Кстати большинство атак на безопасность С/C++ приложений основаны
на том что атакующий просто искусственно передаёт строку недопустимого
размера.

Я также настаиваю что-б вы вообще не использовали эти функции и этот
язык по мере возможности.

И нелишним будет также вам пройти базовый курс обучения С++. Это не в обиду
а - совершенно искренне.
...
Рейтинг: 0 / 0
09.04.2017, 07:26
    #39435358
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование "раздельних" указателей
arrtвсе таки спрошу -- что такое абсурдное, что я здесь написал?
...
Я с С/C++ сталкиваюсь так раз в полгода, так что не надо утрировать.

это не те языки, с которыми можно сталкиваться раз в полгода. ..
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Использование "раздельних" указателей / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]