2014-01-16 2 views
1

Я хочу хранить массив строк, подсчитывать их длину и переупорядочивать их с увеличением длины (наименьшим -> большим) с использованием упомянутого ниже алгоритма. //
Swap содержит относительно большую строку для замены порядка (когда другая мин найдена)
я мог бы использовать перераспределить(), но я не рассматриваю Defend программирования ещеМассивы указателей (строк) сбоев после ввода?

#include <stdio.h> 
#include <stdlib.h> 



int main() 
    { 
     int i,j,N; 
     printf("\n Input amount of alphanumericals: "); 
     scanf("%d",&N); 
      { 
       int min; 
       char *swap=(char*)malloc(sizeof(char)*150); 
       char *A[N],**temp; 
       temp=A; 
       for(i=0;i<N;i++){ 
        printf("\nInput %d element:",i+1); 
        fgets(temp+i,150,STDIN); 
       } 


    printf("\n\nData ["); 
    for(i=0;i<N;i++) 
     printf(" %s",A[i]); 
    printf(" ]\n\n"); 

    //Ins sort 
    for(i=0;i<N;i++){ 
     min=i;//Assume current is min 
     for(j=i+1;j<N;j++){ 
      //Compare assuming min with current 
      if(strcmp(A[j],A[min])<0){ 
       min=j; 
      } 
      //If next is min replace in current position 
     if(min!=i){ 
      swap=A[i]; 
      A[i]=A[min]; 
      A[min]=swap; 
     } 
    } 
    free(swap); 
    printf("\nAfter insertion point algorithm\n"); 
    printf("\n\nInsertion Sorted Data ["); 
    for(i=0;i<N;i++) 
     printf(" %s",A[i]); 
    printf(" ]"); 
    } 
    return 0; 
} 
+0

ли он даже скомпилированные для вас (получает (TEMP + I);)?В любом случае вы указываете здесь указатели и используете его без выделения памяти char * A [N], ** temp; Темп = А; –

+0

Кроме того, temp, который является просто ярлыком для выполнения, получает (A + i) или хранит буквенно-цифровые символы во всех ячейках, да blcc довольно эластичен иногда:/ – hitter

ответ

2

Вы обвязку, чтобы освободить память, которая не была выделена с помощью malloc:

char *A[N],**temp; 
temp = A; // A is an automatic (AKA "stack") variable; now temp points to it as well 
free(temp); // Undefined behavior 

Внутри цикла вы читаете с gets в строки, которые не были выделены:

gets(temp+i); // That's the same as gets(A[i]); Your A[i]s are unallocated. 

В качестве примечания, вы не должны использовать gets, потому что он является основным источником переполнения буфера. Вместо этого используйте fgets и передайте stdin как параметр FILE*. scanf с %20s - еще одна альтернатива ограничению размера.

Кроме того, поскольку i идет от 1 до N включительно, это выражение ссылается на один элемент мимо A массива на последней итерации:

gets(temp+i); // Undefined behavior when i==N 

EDIT: Почему код ниже аварии?

for(i=0;i<N;i++){ 
    printf("\nInput %d element:",i+1); 
    fgets(temp+i,150,STDIN); 
} 

Код ниже падает, потому что вы не выделять память для отдельных строк:

for(i=0;i<N;i++){ 
    printf("\nInput %d element:",i+1); 
    temp+i = malloc(151); // No need to multiply by sizeof(char) or cast to char* 
    fgets(temp+i,150,STDIN); 
} 

Обратите внимание, что вам нужно выделить один дополнительный char для нулевого терминатора.

+0

Он выводит: Вход 1 элемент:
Входной элемент 2: <Я могу ввести здесь >
Элемент ввода 3:
Затем выдает – hitter

+0

@niCk Это потому, что это неопределенное поведение: оно может не сработать два или три раза. Это может даже закончиться. Тем не менее, такая программа может произойти в следующий раз при ее запуске. Если вы хотите увидеть отчет о своих ошибках памяти, запустите [valgrind] (http://valgrind.org/). – dasblinkenlight

+0

отредактирован в fgets(), чтобы избежать ошибок буфера, но не могли бы вы объяснить мне, почему его все еще происходит сбой, я думаю, что я сделал правильные распределения и назначения – hitter

0

Вы не используете gets правильно: взгляните на страницу его руководства [1]. Более того, использование gets не рекомендуется: лучше использовать fgets.

Кроме того, gets не выделяет строку для вас, поэтому, когда вы передаете ей указатель char *, указатель должен указывать на действительное место в памяти. Вместо этого ваш A[n] представляет собой массив оборванных указателей.

Тогда, почему free(temp)? Вы должны позвонить free для каждого указателя, выделенного malloc: не для temp.

Наконец, пожалуйста, отформатируйте свой код: используйте indent.

[1] http://linux.die.net/man/3/gets

+0

Я использовал отступ, формат стал дерьмовым, когда я копирую-скопирую некоторые части, спасибо за документацию – hitter

+0

@niCk - После того, как вы вставляете форматированный код из своего редактора в поле редактирования здесь, выберите свой недавно вставленный код, затем щелкните инструмент _ {} _ над редактором. Если ваш код был отформатирован правильно при вставке, это также поможет отформатировать его. – ryyker