Я работаю над векторным классом на C, и у меня возникли проблемы с использованием getchar(). Хотя я понимаю, что getchar() вернет целочисленный / беззнаковый char, похоже, что он ведет себя иначе, когда значение из getchar() присваивается динамически создаваемому массиву в c. У меня есть код, который я тестировал, чтобы показать, что:

#include <stdio.h>
#include <stdlib.h>
int main(){ 
    char **ptr;
    ptr=calloc(10,sizeof(char));
    unsigned char c = getchar();
    printf("%c\n", c); //this prints a normal value
    ptr[0] = &c;  //dereference the value to assign it to the dynamic array
    printf("%s",ptr[0]); // This prints an odd value
}

И вот результат этого кода:

[jake@shell] hw4 $ ./hw4Test
g
g
g▒▒[jake@shell] hw4 $ ./hw4Test
j
j
j▒~[jake@shell] hw4 $ ./hw4Test
q
q
q▒[jake@shell] hw4 $ ./hw4Test
r
r
r0▒

И когда я попытался внедрить этот код в свой код так далеко, он стал вести себя еще более хаотично:

[jake@shell] hw4 $ ./hw4

Enter the Name : kl
flag
flag
ptr[2] = (null)
ptr[2] = (null)
[jake@shell] hw4 $ ./hw4

Enter the Name : jkla
flag
flag
flag
flag
ptr[4] = (null)
ptr[4] = (null)
ptr[4] = (null)
ptr[4] = (null)
*** glibc detected *** ./hw4: free(): invalid next size (fast):                     0x0000000000705010 ***
======= Backtrace: =========
/lib64/libc.so.6[0x33cae75e66]
/lib64/libc.so.6[0x33cae789b3]
./hw4[0x400691]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x33cae1ed5d]
./hw4[0x400529]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:13 7473045                                    /home/jlongar/Desktop/cStuff/hw4/hw4
00600000-00601000 rw-p 00000000 00:13 7473045                            /home/jlongar/Desktop/cStuff/hw4/hw4
00705000-00726000 rw-p 00000000 00:00 0                                      [heap]
33ca600000-33ca620000 r-xp 00000000 fd:00 130889                         /lib64/ld-2.12.so
33ca81f000-33ca820000 r--p 0001f000 fd:00 130889                         /lib64/ld-2.12.so
33ca820000-33ca821000 rw-p 00020000 fd:00 130889                         /lib64/ld-2.12.so
33ca821000-33ca822000 rw-p 00000000 00:00 0
33cae00000-33caf8a000 r-xp 00000000 fd:00 130934                         /lib64/libc-2.12.so
33caf8a000-33cb18a000 ---p 0018a000 fd:00 130934                         /lib64/libc-2.12.so
33cb18a000-33cb18e000 r--p 0018a000 fd:00 130934                         /lib64/libc-2.12.so
33cb18e000-33cb18f000 rw-p 0018e000 fd:00 130934                         /lib64/libc-2.12.so
33cb18f000-33cb194000 rw-p 00000000 00:00 0
33cca00000-33cca16000 r-xp 00000000 fd:00 131173                         /lib64/libgcc_s-4.4.7-20120601.so.1
33cca16000-33ccc15000 ---p 00016000 fd:00 131173                         /lib64/libgcc_s-4.4.7-20120601.so.1
33ccc15000-33ccc16000 rw-p 00015000 fd:00 131173                         /lib64/libgcc_s-4.4.7-20120601.so.1
7f816bdde000-7f816bde1000 rw-p 00000000 00:00 0
7f816bdf5000-7f816bdf9000 rw-p 00000000 00:00 0
7fff85e61000-7fff85e76000 rw-p 00000000 00:00 0                          [stack]
7fff85f62000-7fff85f63000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                      [vsyscall]
Aborted (core dumped)

Как я могу заставить getchar хорошо работать с динамически создаваемыми массивами в C?

0
SuperNoobAttack 1 Мар 2016 в 00:08

2 ответа

Лучший ответ

Если вы правильно понимаете типы, это работает.

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

int main(){
    char *ptr = calloc(10, 1);  // sizeof(char) is ALWAYS 1
    unsigned char c = getchar();
    printf("%c\n", c); //this prints a normal value
    ptr[0] = c;  //dereference the value to assign it to the dynamic array
    printf("%c", ptr[0]); // This prints an odd value
    free(ptr);
}

Первое правило программирования: не усложняйте вещи слишком сильно. Зачем использовать указатель на указатель (**), если можно использовать только один уровень косвенности - указатель (*).

Второе правило программирования, правильно сопоставляйте типы. Посмотрите различия с вашим кодом выше. Также обратите внимание, что в строке формата printf содержимое ptr [0] является символом, а не символом *.

1
Angus Comber 29 Фев 2016 в 21:19

Проблема в последней printf () .


ptr [0] представляет указатель на char , поэтому, если вы хотите распечатать его содержимое, вам нужно разыменовать его.

Итак, вам нужно заменить printf ("% s", ptr [0]); на printf ("% c", * ptr [0]) .

Видите ли, это % c . Это опять же, потому что ptr [0] - это указатель на char , поэтому * ptr [0] - это char .

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

#include <stdio.h>
#include <stdlib.h>
int main(){
    char **ptr;
    ptr=calloc(10,sizeof(char));
    char c = getchar();
    printf("%c\n", c);
    ptr[0] = &c;
    printf("%c",*ptr[0]);
    return 0;
}
0
Ivan Gandacov 29 Фев 2016 в 21:50