Печать адреса указателя в C [два вопроса] - PullRequest
8 голосов
/ 22 декабря 2011

Я знаю, что мои вопросы очень просты, но их поиск в Google не принес мне никаких полезных результатов ... Возможно, они слишком простые !!

Нет.1

char* createStr(){
    char* str1 = malloc(10 * sizeof(char));
    printf("str1 address in memory : %p\n", &str1);
    return str1;
}

int main(void){
    char* str2 = createStr();
    printf("str2 address in memory : %p\n", &str2);
}

Результат:

str1 address in memory : 0x7fffed611fc8
str2 address in memory : 0x7fffed611fe8

Почему адреса отличаются от функции createStr () и как я могу освободить (str1) ???

Нет.2

int main(int argc, int *argv[]){
    printf("Basename is %s ", (char*) argv[0]);
    if(argc > 1 ){
        printf("and integer arg is : %d.\n", (int) *argv[1]);
    }
}

Если я компилирую и запускаю $ ./test 3, как я могу получить int 3?

Результат:

Basename is ./test and integer arg is : 1380909107.

Ответы [ 5 ]

8 голосов
/ 22 декабря 2011

Комментарии встроены!

Нет. 1

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

char* createStr(){
    char* str1 = malloc(10 * sizeof(char));
    /* str1 is a local variable which is allocated in 
       stack and not in heap */
    /* But the dynamic memory allocation is done in 
       heap so malloc returns a portion of memory from
       heap and str1 is made to point to that!
    */
    /*
    aaaa (stack)    bbbb (heap)
    +--------+      +-+-+-------+-+
    |  str1  |----->|0|1| ..... |9|
    +--------+      +-+-+-------+-+
    */

    printf("address of str1 in memory : %p\n", &str1);
    /* prints aaaa and not bbbb */
    /* to print the base address of the allocated memory, 
    printf("str1 address in memory : %p\n", str1);
    */
    printf("address of the allocated memory inside func : %p\n", str1);

    return str1;
}

int main(void){
    char* str2 = createStr();
    /* str2 is a local variable to main and so it is
       allocated in the stack 
    */
    /*
    cccc (stack)    bbbb (heap)
    +--------+      +-+-+-------+-+
    |  str2  |----->|0|1| ..... |9|
    +--------+      +-+-+-------+-+
    */
    printf("address of str2 in memory : %p\n", &str2);
    /* the above will print the address of the str2 
       (which is cccc) but not where it is pointing 
       to (bbbb) ..
    */
    /* So to print the base address of where it is 
       pointing to (bbbb), 
    printf("str2 address in memory : %p\n", str2);
    */
    printf("address of the allocated memory inside main : %p\n", str2);
}

№ 2.

#include <stdio.h>

int atoi(char a[])
{
        int i, n=0;

        for (i=0 ; a[i] >= '0' && a[i] <= '9' ; i++)
                n = 10 *n + (a[i]-'0');

        return n;
}

int main(int argc, char *argv[]){
    printf("Basename is %s ", (char*) argv[0]);
    if(argc > 1 ){
        printf("and integer arg is : %d.\n", atoi(argv[1]));
    }
}


$ gcc atoi.c -o atoi
$ ./atoi 3
Basename is ./atoi and integer arg is : 3.
$

Обратите внимание:

  • w.r.t # 2: в main () это должно быть char * argv[], а не int * argv[]
5 голосов
/ 22 декабря 2011

Чтобы исправить первый:

char* createStr(){
    char* str1 = malloc(10 * sizeof(char));
    printf("str1 address in memory : %p\n", str1);
    return str1;
}

int main(void){
    char* str2 = createStr();
    printf("str2 address in memory : %p\n", str2);
    free(str2);
}

В противном случае вы печатаете адрес переменной (str1 и str2), а не адрес, на который указывает переменная.

Я также добавил вызов free(), чтобы исправить утечку памяти.

Что касается второго, , вам нужно использовать atoi() для преобразования строки в int:

printf("and integer arg is : %d.\n", atoi(argv[1]));
3 голосов
/ 22 декабря 2011

Вопрос 1 :

Адреса отличаются, потому что вы берете адреса указателей, а не адреса переменных, хранящихся в указателях.Так как str2 существует в стеке main и str1 в стеке createStr, их адреса различны.

Вы можете освободить str1, освободив str2, потому что они указываютв том же месте.Адрес, на который указывает str1, копируется внутри str2, когда str1 возвращается из createStr.

Вопрос 2 :

Использование int value = atoi(argv[1]);Это преобразует char* в int.

0 голосов
/ 22 декабря 2011

Для второго примера: *argv[1] - это char * (то есть "3")
Если вы хотите отобразить "3", вы должны использовать printf("%s\n", *argv[1]); или получить целое число из строки, используя atoi().
Может быть, вы даже можете попробовать написать свою собственную версию atoi()!

0 голосов
/ 22 декабря 2011

Первый пример выделяет строку, затем возвращает указатель на нее. Когда вы делаете присваивание из возвращаемого значения метода, вы просто назначаете указатель. Вы только когда-либо сделали одну строку.

Во втором примере вы хотите atoi.

...