2015-04-24 2 views
0

Я хочу удалить i-й член массива строк и принести каждый элемент, который приходит после него на одно место (i + 1-й член в i и т. Д.). Я придумал следующий код:обмен между членами массива строк в C

for (int j = i; j < arrSize - 1; j++) { 
     strcpy(members[j],members[j+1]); 
    } 
    free(members[arrSize-1]); 

Но это заставило меня думать, что это может быть неправильно. Например, если элемент i-го места содержит имя «Джон», а элементы (i + 1) -th place содержат имя «Joshua», что означает, что каждая строка имеет разную длину, будет ли какая-либо память утечки или любые проблемы? Заранее спасибо!

EDIT: Definiton участников:

members = malloc(maxMembersNum * sizeof(char*)); 
+0

и что такое '' массив строк'? Я имею в виду, показать нам определение «членов». –

+0

как вы распределяете для 'members'? – holgac

+0

Невозможно ответить на этот вопрос, не видя объявления «членов» и как он построен. C имеет несколько способов сделать это. –

ответ

1

Вместо того, чтобы скопировать содержимое строк, почему бы не переместить указатели вокруг? То есть:

for (int j = i; j < arrSize - 1; j++) { 
    char *temp = members[j]; 
    members[j] = members[j+1]; 
    members[j+1] = temp; 
} 
free(members[arrSize-1]); 
+0

Это работает только при наличии указателей. ОП не показал нам этого. –

+0

@LeeDanielCrocker Они должны быть, иначе вызов 'strcpy' и' free' в конце не имеет смысла. – MicroVirus

+0

На самом деле, нет никакого кода, в котором они оба имеют смысл. Либо это массив указателей, и в этом случае ему нужен свободный, но не strcpy, или это массив 2d char, и в этом случае ему нужен strcpy, но не бесплатный. –

1

Как указано в комментариях, определение членов определяет результат функции.

Если:

char* members[];

, то это массив указателей, используя STRCPY перепишет память, и вы будете в конечном счете крах, если все эти буферы не выделяются и тот же размер. В этом случае, вы можете просто скопировать указатели с

members[j] = members[j+1] 

если:

std::string members[];

, то вы можете рассматривать его как обычный массив и обойтись без зЬгсра и бесплатно (просто использовать =).

если:

члены символьные [80] [80]; // фиксированный размер предварительно выделенный буфер

тогда ваш код будет работать, но бесплатный не будет.

+0

'std :: string members [];' ... in 'C'? как? –

+0

Извините, для этого потребуется C++. Я пропустил ограничение OP только на «C». – Brad

-1

Было бы проще, если бы линии и arrSize были членами структуры, которые вы могли бы пройти в качестве единицы, но отсутствует, что:

void remove_by_index(char **lines, int line, int *arrSize) { 
    if (line >= *arrSize) return; 
    *arrSize -= 1; 

    if (lines[line]) free(lines[line]); 
    memmove(lines + line, lines + line + 1, ((*arrSize - line) * sizeof(char *))); 
    lines[*arrSize] = NULL; 
} 

Строго говоря, либо arrSize должен измениться, чтобы отразить удаление или иначе удаленная ячейка должна быть отмечена с помощью NULL, но не обязательно делать то, что я сделал здесь (хотя это не плохая идея).

Также обратите внимание, что это не сработает, если два элемента массива указывают на одну и ту же строку, как и другие ответы здесь - для этого вам понадобится более сложная структура данных.

+0

'free (lines [* arrSize]);' неверно. 'free' должен применяться к' lines [line] 'before' memmove'. – BLUEPIXY

+0

Вы правы. Я исправлю, когда попаду на рабочий стол. –

Смежные вопросы