Нужна помощь в копировании c-строк из встроенной выборки SQL в другую c-строку в отдельной структуре

Я наткнулся на программу, которая использует встроенный SQL для извлечения строк из таблицы базы данных, сохраняет данные строк в структуре, а затем обрабатывает эти данные, а результаты сохраняются в другой структуре и помещаются в связанный список. Структура, в которой хранятся данные выборки, выглядит следующим образом:

struct rowstruct {
    char    *first;
    char    *last;
    long    amt;
}   client;

и моя структура, которую я использую для хранения обработанных данных (и впоследствии в качестве узла в моем связанном списке), выглядит так:

struct mystruct {
        char    *firstN;
        char    *lastN;
        long    total;
    }   data;

Моя проблема в том, что при каждом цикле выборки мне нужно копировать значения client.first и client.last в data.firstN и data.lastN, но я не могу заставить его работать. Следующее, используя оператор присваивания, просто копирует указатель, а не значение:

data.firstN = client.first;
data.lastN = client.last;

Если я вывожу data.firstN и data.lastN после первой итерации моего цикла, значения отображаются правильно, но после второй итерации выборки первый узел в моем списке будет отражать значения из второй выборки, а не первый.

strcpy скомпилируется, но во время выполнения произойдет сбой из-за ошибки сегментации, которая, если читать здесь, связана с использованием char*, хотя я не думаю, что могу использовать char[] или строку при извлечении данных с помощью встроенного SQL, поэтому это похоже на тупик.

Я уверен, что есть способ сделать это, и, вероятно, для большинства здесь это очевидно, но я в растерянности. Любая помощь будет оценена по достоинству.

Спасибо!


person PSUlion01    schedule 12.10.2012    source источник
comment
Вы выделили память для mystruct char *s? т.е. data.firstN = malloc (sizeNeeded) - возможно через strlen - тогда strcpy обратите внимание, что я бы предпочел strncpy или другую безопасную альтернативу (strcpy_s?)   -  person im so confused    schedule 12.10.2012
comment
mystruct кажется избыточным, хотя   -  person Alexander    schedule 12.10.2012
comment
Извините за путаницу с mystruct. Это больше, чем показано выше ... Не понимал, насколько запутанно я сделал это в посте.   -  person PSUlion01    schedule 14.10.2012
comment
@ AK4749 - Смотрите мой комментарий ниже. Теперь я вижу, что я делал неправильно, и предложенное решение было довольно простым, хотя ваш комментарий проясняет, как я буду выделять память для char*. Спасибо   -  person PSUlion01    schedule 14.10.2012


Ответы (1)


Если в коде указано скопировать указатель, именно это и происходит.

Вероятно, вы хотите что-то вроде

data.firstN = strdup (client.first);
data.lastN = strdup (client.last);

Есть и другие способы сделать то же самое в C++, но это должно помочь вам преодолеть горб.


Вам не нужно повторно объявлять структуру. Вместо этого вы можете объявить data с помощью

struct rowstruct data;
person wallyk    schedule 12.10.2012
comment
Если вы копируете строку с strdup, имейте в виду, что вам придется free ее, когда вы закончите. Обычно это делается с помощью delete в C++, но это функция C, которая выделяет ее с помощью malloc, а не new. linux.die.net/man/3/strdup - person Geoff Montee; 13.10.2012
comment
@wallyk - Спасибо ... Решение, предложенное моим профессором, состояло в том, чтобы объявить firstN и lastN как массивы символов, например char первыйN[30]. Меня беспокоило выделение ненужной памяти (или ее недостаточно), но, поскольку данные поступают из предопределенных полей базы данных, он сказал, что можно использовать фиксированный размер массива символов. Я собираюсь попробовать ваше предложение, просто чтобы посмотреть, как оно работает. Что касается повторного объявления структуры, у mystruct были другие члены, которые не были частью оригинала. - person PSUlion01; 14.10.2012
comment
@Geoff - Спасибо, что указали на часть управления памятью. Мне нужно потратить немного больше времени и действительно попытаться лучше понять все в моей программе. Я довольно новичок в программировании, без мастерства или какого-то одного языка. Эта конкретная задача заставила меня работать с кодом C (из-за встроенного SQL), но я больше знаком с C++, поэтому я думаю, что мой код сейчас немного Франкенштейн. Как только я закончу с этим, возможно, я смогу добавить его в эту ветку для комментариев/предложений? Кажется, что лучший способ учиться — это попросить других указать на проблемы и более предпочтительные подходы. - person PSUlion01; 14.10.2012