Запись указателя в массив указателей
От: wbear  
Дата: 24.04.23 17:00
Оценка:
Добрый вечер!

Делаю лабу.
Задача такая. Динамически создаем массив указателей. Который должен хранить в качестве элементов указатели на строки.
Последний элемент в массиве NULL.
Для работы с памятью нужно использовать функции malloc. Для изменения размера выделенной памяти функцию realloc.

Память под массив выделил. Выделил для строки тоже динамически память. Расширил ранее выделенную память под 2-а элемента.

При попытке записать в первый элемент массива указатель строки, компилятор ругается на такую запись -> ( *((DWORD*)pNewMem+v3-1) = pS;//????? )
Че иму не так.




char* CloneString(char* lpString)
{
    int len = strlen(lpString);

    char* ptrMemString = (char*)malloc(len+1);

    if(ptrMemString)
        strcpy(ptrMemString, lpString);

    return ptrMemString;
}



    int v3=0;
    DWORD* pMemory;

    pMemory = (DWORD*)malloc(sizeof(DWORD));
    *((DWORD*)pMemory+v3)=NULL;

    DWORD* v8;

    pS = (DWORD*)CloneString("d://Work//CxFViewer//CxFViewer//4//data//cbf//AAG169.cbf");

    if(pS)
    {

        printf("%s\n", pS);

        DWORD* pNewMem = (DWORD*)realloc(pMemory, (4*++v3)+4);            

        if(!pNewMem)
        {
            free(v8);
            free(pMemory);
            return 0;
        }

        pMemory = pNewMem;

        *((DWORD*)pNewMem+v3-1) = pS;//?????

        *((DWORD*)pMemory+v3)=NULL;
    }



Сильно не пинайте. я только начал учить С
Re: Запись указателя в массив указателей
От: T4r4sB Россия  
Дата: 24.04.23 17:10
Оценка: +1
Здравствуйте, wbear, Вы писали:
*((DWORD*)pNewMem+v3-1) = pS;//????? )

Выражение внутри скобок имеет тип DWORD*
значит разыменованное выражение имеет тип DWORD
А pS, судя по всему, имеет типа DWORD*
И ещё у тебя везде путаются указатели на строки и указатели на указатели на строки

Попробуй так:
*((DWORD**)pNewMem+v3-1) = pS;

А лучше

pNewMem[v3-1] = pS;



А вообще у тебя походу DWORD используется для хранения указателя, это плохо, ты используешь не тот тип, к тому же их размеры совпадают не везде

Если хоть как-то убрать всю путаницу, то будет примерно так (набирал в браузере):
  Скрытый текст
   int len=1;
    char** pMemory;

    pMemory = (char**)calloc(sizeof(char*), len);

    pS = (char*)CloneString("d://Work//CxFViewer//CxFViewer//4//data//cbf//AAG169.cbf");

    if(pS)
    {

        printf("%s\n", pS);
        ++len;
        char** pNewMem = (char**)realloc(pMemory, len * sizeof(char*));           

        if(!pNewMem)
        {
            free(pMemory);
            return 0;
        }

        pMemory = pNewMem;
        pMemory [len-1] = pS;
    }



А лучше такие вещи делать на С++. А если приходится постоянно дёргать динамическую память на сишке — это значит, ты либо что-то делаешь не так (например, нельзя ли заранее выделить блоки нужного типа и размера для начала работы алгоритма), либо выбрал не тот язык для задачи.
Отредактировано 24.04.2023 17:12 T4r4sB . Предыдущая версия . Еще …
Отредактировано 24.04.2023 17:11 T4r4sB . Предыдущая версия .
Re: Запись указателя в массив указателей
От: AleksandrN Россия  
Дата: 25.04.23 10:20
Оценка: +1
Здравствуйте, wbear, Вы писали:


W>

W>char* CloneString(char* lpString)
W>{
W>    int len = strlen(lpString);

W>    char* ptrMemString = (char*)malloc(len+1);

W>    if(ptrMemString)
W>        strcpy(ptrMemString, lpString);

W>    return ptrMemString;
W>}


Для выделения памяти под новую строку и копирования в неё другой строки есть стандартная функция strdup.
Re: Запись указателя в массив указателей
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 25.04.23 18:52
Оценка:
Здравствуйте, wbear, Вы писали:

W> *((DWORD*)pNewMem+v3-1) = pS;//?????


Как Вам уже пояснили, у Вас путаница с типами указателей. Вообще, вот такое приведение типа указателя "по месту" лучше использовать как можно реже — например, когда работаете с неструктурированной памятью, и нужно обращаться к произвольным типам данных, расположенным по произвольным адресам. Коли у Вас есть определенная структура данных — "массив указателей на строки", то и объявляйте именно массив — char ** или char * [], преобразуя тип указателя только в моменты получения блока от malloc/realloc, а в остальное время работая с блоком, как с обычным массивом переменной длины, с помощью индекса или "бегущего" указателя.
Re: Запись указателя в массив указателей
От: BSOD  
Дата: 27.04.23 11:24
Оценка: +1
Здравствуйте, wbear, Вы писали:

W>
W>    pS = (DWORD*)CloneString("d://Work//CxFViewer//CxFViewer//4//data//cbf//AAG169.cbf");
W>


"Дублировать" нужно обратный слеш (\\), а прямой не нужно. Т.к. обратый слеш — это эскейп-символ, а прямой — нет.
Обычно, файловая система винды проглатывает пути с "//", но в других случаях могут быть проблемы.
Sine vilitate, sine malitiosa mente
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.