2013-06-17 2 views
2

Я пытаюсь получить доступ к массиву строк с помощью указателей. Кажется, что он работает нормально, когда память распределяется, но как-то значения теряются, если я пытаюсь снова повторить указатель. Однако указанные адреса верны.C Указатель на указатель - список строк доступа

char **rows = (char **) malloc(sizeof(char) * 8); 
int i; 

for (i = 0; i < 5; i++) { //first time 
    *(rows + i) = malloc(sizeof(char) * 8); 
    sprintf(*(rows + i), "0x10%d", i); 
    printf("---%[email protected]%x", *(rows + i), (rows + i)); 

} 

for (i = 0; i < 5; i++) { //second time 
    printf("++++%[email protected]%x", *(rows + i), (rows + i)); 
} 

Формат вывода: Значение @ адрес

Выше (первый контур) будет производить следующий вывод:

[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

Что является правильным interms значений и соответствующих адресов. Но как-то значения теряются, когда я пытаюсь использовать их снова, ниже выход из второго контура:

[email protected] 
[email protected] 
[email protected] 
[email protected] 
[email protected] 

Как его ясно видеть, что адрес правильно для всех пяти узлов, но значения для запуска узлов отсутствуют ,

Вопрос:

Почему значения отсутствуют по адресу 0x1007e0 и 0x1007e8 с действительным адресом?

Спасибо,

+7

Интересно, действительно ли вы имели в виду: 'char ** rows = (char **) malloc (sizeof (char *) * 8);' - выделение 8 указателей на символы, а не 8 символов. – mah

+0

#mah Спасибо, и в этом была проблема. Интересно, как все-таки это показало некоторые ценности! Любые мысли по этому поводу? – ila

+0

@ user2492889 Это неопределенное поведение: авария или перезапись не требуется, ваша программа могла бы даже работать до конца, если malloc был немного более щедр при распределении дополнительной памяти за пределы того, что вы просили. – dasblinkenlight

ответ

2

Я думаю, что это, возможно, придется делать с вашим код не выделять достаточно мест для указателей: так как вы выделяете восемь указателей, а не восемь символов, эта линию

char **rows = (char **) malloc(sizeof(char) * 8); 

должен быть

char **rows = malloc(sizeof(char*) * 8); 

Это изменение устраняет проблему (demo on ideone).

+0

Как насчет 'char ** rows = malloc (sizeof (void *) * 8);'. Никакой кастинг возврата malloc, и я лично предпочитаю 'void *' просто потому, что легко отличить, что на него ссылается размер указателя. – Jite

+1

@jate мое предпочтение размеру будет фактически 'malloc (sizeof (* rows));' - это общий шаблон, который я использую, чтобы включить изменение типа переменной, чтобы не мешать распределению (хотя, конечно, изменяясь от один тип указателя на другой не является изменением размера). – mah

+0

@Jite Правильно, это C, а не C++, поэтому нет необходимости бросать. Я скопировал из OP, поэтому я сохранил актерский состав, но это действительно не нужно. – dasblinkenlight