2016-09-10 4 views
-1

Я новичок в обучении C, и я тренировался с выделениями памяти и указателями, однако я столкнулся с проблемой, с которой я не могу обойтись. Когда я отлаживаю приведенный ниже код, я получаю сообщение об ошибке «Не удается получить доступ к памяти в адресе» для строки vowelStore [x] = vowelA;C Не удается получить доступ к памяти по адресу

char *DissVowel(char phrase[50]) 
{ 
    char vowelStore[50]; 

    for(int x=0; x< strlen(phrase); x++) 
    { 
     switch(phrase[x]) 
     { 
      char *vowelA = malloc(sizeof(*vowelA)); 

      case 'a': 
       vowelA = phrase[x]; 
       vowelStore[x] = vowelA; 
       free(vowelA); 
       break; 
      default: 
       break; 
     } 
    } 

    return vowelStore; 
} 

В основном, эта функция принимает в массив символов (строка фразы), затем циклы через каждый символ, и если текущий символ «а», часть памяти выделяется, и «» будет храниться в выделенном пространстве. Затем адрес этого пространства, содержащего «a», будет храниться в отдельном массиве, который будет содержать несколько адресов. Затем функция возвращает этот массив адресов.

Любая помощь очень ценится!

+0

'vowelA = фраза [x];' перезаписала указатель на память, полученный из 'malloc', и создаст предупреждение компилятора для другого типа. Как только вы уничтожили указатель, полученный «malloc», вы не сможете позже «освободить» его. В любом случае 'char * vowelA = malloc (sizeof (* vowelA));' выделяет ** 1 байт ** памяти. –

+0

Массив 'char' не может хранить символ' char * '. (Несвязанный - или, возможно, связанный из-за вашего непонимания указателей), но сам 'vowelA' не должен быть символом' char * ', и ему не нужно быть' sizeof (любой указатель) '.) – usr2564301

+0

'char * vowelA = malloc (sizeof (* vowelA));' Это может быть не выполнено. – BLUEPIXY

ответ

0

С кодом возникает ряд проблем.

char *DissVowel(char phrase[50]) 

Это законно, но вводит в заблуждение. C фактически не имеет параметров массива. Если вы определите, что выглядит как параметр массива, как вы это сделали, он «настроен», чтобы стать параметром указателя, и длина игнорируется. Выше в точности эквивалентно:

char *DissVowel(char *phrase) 


for(int x=0; x< strlen(phrase); x++) 

Это допустимо, но неэффективно. strlen() должен отсканировать строку с начала, чтобы найти завершающий символ '\0', который отмечает конец строки. Вы вызываете strlen на каждой итерации. Либо сохраните длину строки в переменной и проверьте, что в состоянии, либо используйте другое условие, такое как phrase[x] != '\0'. (Очень незначительный пункт: i является более условным названием для итерационных переменного, используемых в качестве индекса.)

switch(phrase[x]) 
    { 
     char *vowelA = malloc(sizeof(*vowelA)); 

     case 'a': 
      /* ... */ 
      break; 
     default: 
      break; 
    } 

switch утверждения по существу вычисляется goto. Когда выполняется switch, он перескакивает непосредственно либо на метку case 'a':, либо на метку default:, пропуская что-либо между ними. Поскольку это входит в новую область, память выделяется для объекта-указателя vowelA, но его инициализация не выполняется, поэтому vowelA имеет неопределенное значение.

return vowelStore; 

vowelStore является локальной переменной массива. В этом контексте он «преобразуется» в указатель на исходный элемент массива, эквивалентный &vowelStore[0]. Переменная массива перестает существовать, когда вы возвращаетесь из функции, поэтому возвращаемое вами значение является обвисшим указателем.

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

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