Я должен спросить: вы фактически выделили пространство для переменных qptr->name[]
. Если ваша структура просто что-то вроде:
struct line {
int front;
int numElements;
int queueSize;
char *name[100]; // or char **name where only first level is allocated.
}
тогда вы этого не сделаете, что приведет к неопределенному поведению, когда вы попытаетесь strcpy
ввести имя.
Кроме этого, я бы предложил то же самое, что и всем, кто представляет проблему.
- Что вы ожидали?
- Что на самом деле произошло?
- Покажите нам код (вы уже сделали этот бит, я включил его для полноты).
И временно вставьте в эту функцию некоторые операторы printf
, чтобы вы могли видеть соответствующие поля до и после. Обычно это приводит к тому, что точно видит, что идет не так.
Судя по вашим комментариям, в вашей структуре есть массив из 50 символьных указателей, ни один из которых не был выделен. Вероятно, вы стремитесь к массиву символьных указателей, каждый из которых указывает на строку из 50 символов.
Я бы предложил, чтобы ваша структура содержала:
char *name[MAX_SZ]; // or a variable length array (either c99 or malloc trickery).
и изменить:
strcpy(qPtr->name[(qPtr->front+qPtr->numElements)%qPtr->queueSize], name);
до:
qPtr->name[(qPtr->front+qPtr->numElements)%qPtr->queueSize] = strdup (name);
Просто помните, что когда вы извлекаете это из списка, вы отвечаете за его освобождение, когда закончите.
Если вам не повезло оказаться в системе, в которой нет strdup
, ну, вот тот, который я подготовил ранее: -)
Для чего-то я выкопал из своей базы кода старую реализацию, которую вы можете использовать по своему усмотрению:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Would go in header file.
typedef enum {
QERR_OKAY,
QERR_NOMEM,
QERR_INVALID,
QERR_FULL
} eQueueErr;
typedef struct {
size_t capacity;
size_t used;
size_t first;
size_t next;
char **list;
} tQueue;
const char *qErr (eQueueErr);
void qDump (char*,tQueue*);
tQueue *qCreate (size_t);
eQueueErr qPut (tQueue*,char*);
void qClear (tQueue*);
void qDestroy (tQueue*);
// Would go in C file.
// Returns textual representation of an error.
const char *qErr (eQueueErr e) {
if (e == QERR_OKAY) return "Okay";
if (e == QERR_NOMEM) return "NoMem";
if (e == QERR_INVALID) return "Invalid";
if (e == QERR_FULL) return "Full";
return "?????";
}
// Dump function for debugging.
void qDump (char *desc, tQueue *q) {
size_t i, j;
printf ("%s: ", desc);
printf ("capacity = %d, ", q->capacity);
printf ("used = %d, ", q->used);
printf ("first = %d, ", q->first);
printf ("next = %d,", q->next);
if (q->used > 0) {
for (i = q->first, j = q->used; j > 0; i = (i + 1) % q->capacity, j--)
printf (" %d=[%s]", i, q->list[i]);
} else {
printf (" no entries");
}
printf ("\n\n");
}
// Create a queue os a specified size.
tQueue *qCreate (size_t capacity) {
tQueue *q;
size_t i;
// Need to create both the queue and the queue elements.
if ((q = malloc (sizeof (tQueue))) == NULL)
return NULL;
if ((q->list = malloc (capacity * sizeof (char *))) == NULL) {
free (q);
return NULL;
}
// Set up accounting info and return it.
q->capacity = capacity;
q->used = q->first = q->next = 0;
return q;
}
// Put something on the queue, return error if full, NULL or no memory available.
eQueueErr qPut (tQueue *q, char *s) {
// Check if trying to put NULL or queue is full.
if (s == NULL) return QERR_INVALID;
if (q->used == q->capacity) return QERR_FULL;
// Allocate new string and store if okay.
q->list[q->next] = strdup (s);
if (q->list[q->next] == NULL) return QERR_NOMEM;
// Update accounting info and return success.
q->next = (q->next + 1) % q->capacity;
q->used++;
return QERR_OKAY;
}
// Get an element from the queue (or NULL if empty).
char * qGet (tQueue *q) {
char *s;
// Just return NULL if empty.
if (q->used == 0) return NULL;
// Get it and adjust accounting info, then return it.
s = q->list[q->first];
q->first = (q->first + 1) % q->capacity;
q->used--;
return s;
}
// Clear a queue.
void qClear (tQueue *q) {
size_t i, j;
for (i = q->first, j = q->used; j > 0; i = (i + 1) % q->capacity, j--)
free (q->list[i]);
q->used = q->first = q->next = 0;
}
// Destroy a queue.
void qDestroy (tQueue *q) {
qClear (q);
free (q->list);
free (q);
}
// Test program.
static char *nextLetter (void) {
static char buffer[2];
static char ch = 'A';
buffer[0] = ch;
buffer[1] = '\0';
ch = (ch == 'Z') ? 'A' : (ch + 1);
return buffer;
}
static void bigPut (tQueue *q, size_t num) {
char *val;
while (num-- > 0) {
val = nextLetter();
printf ("Putting '%s' returns: %s\n", val, qErr (qPut (q, val)));
qDump ("After putting", q);
}
}
static void bigGet (tQueue *q, size_t num) {
char *val;
while (num-- > 0) {
val = qGet (q);
printf ("Getting returns [%s]\n", val ? val : "<<null>");
qDump ("After getting", q);
}
}
int main (void) {
tQueue *x;
size_t i;
char *val;
if ((x = qCreate (5)) == NULL) return 1;
qDump ("Create empty", x);
printf ("Putting NULL returns: %s\n", qErr (qPut (x, NULL)));
qDump ("After putting", x);
bigPut (x, 6);
bigGet (x, 4);
bigPut (x, 2);
bigGet (x, 4);
bigPut (x, 3);
qClear (x);
qDump ("After clear", x);
qDestroy (x);
return 0;
}
При запуске этой программы генерируется следующий отладочный вывод:
Create empty: capacity = 5, used = 0, first = 0, next = 0, no entries
Putting NULL returns: Invalid
After putting: capacity = 5, used = 0, first = 0, next = 0, no entries
Putting 'A' returns: Okay
After putting: capacity = 5, used = 1, first = 0, next = 1, 0=[A]
Putting 'B' returns: Okay
After putting: capacity = 5, used = 2, first = 0, next = 2, 0=[A] 1=[B]
Putting 'C' returns: Okay
After putting: capacity = 5, used = 3, first = 0, next = 3, 0=[A] 1=[B] 2=[C]
Putting 'D' returns: Okay
After putting: capacity = 5, used = 4, first = 0, next = 4, 0=[A] 1=[B] 2=[C] 3=[D]
Putting 'E' returns: Okay
After putting: capacity = 5, used = 5, first = 0, next = 0, 0=[A] 1=[B] 2=[C] 3=[D] 4=[E]
Putting 'F' returns: Full
After putting: capacity = 5, used = 5, first = 0, next = 0, 0=[A] 1=[B] 2=[C] 3=[D] 4=[E]
Getting returns [A]
After getting: capacity = 5, used = 4, first = 1, next = 0, 1=[B] 2=[C] 3=[D] 4=[E]
Getting returns [B]
After getting: capacity = 5, used = 3, first = 2, next = 0, 2=[C] 3=[D] 4=[E]
Getting returns [C]
After getting: capacity = 5, used = 2, first = 3, next = 0, 3=[D] 4=[E]
Getting returns [D]
After getting: capacity = 5, used = 1, first = 4, next = 0, 4=[E]
Putting 'G' returns: Okay
After putting: capacity = 5, used = 2, first = 4, next = 1, 4=[E] 0=[G]
Putting 'H' returns: Okay
After putting: capacity = 5, used = 3, first = 4, next = 2, 4=[E] 0=[G] 1=[H]
Getting returns [E]
After getting: capacity = 5, used = 2, first = 0, next = 2, 0=[G] 1=[H]
Getting returns [G]
After getting: capacity = 5, used = 1, first = 1, next = 2, 1=[H]
Getting returns [H]
After getting: capacity = 5, used = 0, first = 2, next = 2, no entries
Getting returns [<<null>]
After getting: capacity = 5, used = 0, first = 2, next = 2, no entries
Putting 'I' returns: Okay
After putting: capacity = 5, used = 1, first = 2, next = 3, 2=[I]
Putting 'J' returns: Okay
After putting: capacity = 5, used = 2, first = 2, next = 4, 2=[I] 3=[J]
Putting 'K' returns: Okay
After putting: capacity = 5, used = 3, first = 2, next = 0, 2=[I] 3=[J] 4=[K]
After clear: capacity = 5, used = 0, first = 0, next = 0, no entries