Brian Oh Ответов: 4

В "C" как я могу создать массив в struct во время выполнения?


Я пишу свою вторую программу "С" и хотел бы решить следующую проблему:

У меня есть структура следующим образом:

struct ST {
  char *sFile;
  FILE *pfFile;
  char** arsFileData;
} _st1, _st2;


Переменная "arsFileData" в структуре представляет собой массив или строки, и ее размер неизвестен до времени выполнения. Единственный способ, которым я смог инициализировать его до сих пор, заключается в следующем:

char* arsFile1Data[iLineTot1];
_st1.arsFileData = arsFile1Data;


"arsFile1Data" используется для хранения текстовых строк из файла. Я использую malloc для выделения памяти для каждой строки.

Как я могу создать массив в одной строке, а не сначала создать отдельную переменную?

Что я уже пробовал:

Искал в интернете и здесь и экспериментировал безуспешно.

4 Ответов

Рейтинг:
33

Richard MacCutchan

_st1.arsFileData = (char**)malloc(iLineTot1 * sizeof(char*));


Рейтинг:
2

OriginalGriff

Чтобы добавить к тому, что сказали другие, не делайте этого:

char* arsFile1Data[iLineTot1];
_st1.arsFileData = arsFile1Data;
Поскольку этот код выполняется в функции, массив указателей на ваши строки создается в стеке, а пространство освобождается и используется повторно сразу же после завершения вашей функции. Это нормально - но плохая практика - в main функция, но может вызвать некоторые очень странные ошибки в других функциях, которые невероятно трудно отследить. Технический термин-это а dangling reference или dangling pointer[^]

Вместо этого вам нужно выделить место в куче с помощью malloc как показал Ричард, а затем использовать malloc опять же, чтобы создать каждую отдельную строку:
int iLineTot1 = 2;
_st1.arsFileData = (char**) malloc(iLineTot1 * sizeof(char*));
_st1.arsFileData[0] = (char*) malloc(sizeof(char) * 10);
_st1.arsFileData[1] = (char*) malloc(sizeof(char) * 16);


Brian Oh

Спасибо. Я приняла предложение Ричарда, потому что оно было первым, а с остальным я справляюсь нормально. Однако были отмечены дополнительные детали.

Рейтинг:
2

Rick York

Вы можете выделить массив в одной строке кода, но для его загрузки требуется дополнительный код. Сообщение Ричарда показывает, как выделить память для массива. Вот фрагмент кода, который может помочь вам загрузить массив.

struct ST
{
    char * sFile;
    FILE * pfFile;
    int    lineCount;
    int    maxLines;
    char** arsFileData;
};

void InitializeStructure( struct ST * pst, int lines )
{
    pst->arsFileData = (char **) malloc( lines * sizeof(char*) );
    pst->maxLines = lines;
    pst->lineCount = 0;
    pst->sFile = NULL;
    pst->pfFile = NULL;
}

void ReleaseStructure( struct ST * pst )
{
    int x;
    for( x = 0; x < pst->lineCount; ++x )
         free( pst->arsFileData[ x ] );
    free( pst->pst->arsFileData );
}

void AddTextLine( struct ST * pst, const char * text )
{
    int index = pst->lineCount;
    if( index >= pst->maxLines )
        return;    // request exceeds available storage

    pst->arsFileData[ index ] = strdup( text );
    ++pst->lineCount;
}
Я включил функцию, чтобы освободить выделенную память, потому что хорошо себя ведет программное обеспечение всегда убирает за собой. Чтобы использовать его вы могли бы сделать это :
struct ST st1;

InitializeStructure( & st1, 128 );    // initialize to expected number of entries

AddTextLine( & st1, "this" );
AddTextLine( & st1, "that" );
AddTextLine( & st1, "other" );
AddTextLine( & st1, "who" );
AddTextLine( & st1, "what" );
AddTextLine( & st1, "when" );
AddTextLine( & st1, "where" );
AddTextLine( & st1, "why" );

// do something with st1 here

ReleaseStructure( & st1 );       // release allocated memory


Brian Oh

Спасибо за информацию. Я принял Ричарда, потому что он был первым, и я справляюсь с остальными нормально и аналогичным образом, но дополнительная информация отмечена.

Рейтинг:
0

CPallini

Цитата:
Как я могу создать массив в одной строке, а не сначала создать отдельную переменную?
Вы не можете: массив является отдельная переменная.
То ST.arsFile1Data указатель создается при создании экземпляра объекта struct а затем его значение изменяется, чтобы указать область памяти массива.