Как передать адрес двойного указателя другому двойному указателю

#c #pointers #double-pointer

#c #указатели #двойной указатель

Вопрос:

Как я могу передать адрес двойного указателя другому? У меня есть этот код, и он работает корректно, только если я задаю строку с комментариями. Почему размер отличается?

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
    char *s1[]={"this","is","a","test"};
    char **s2;
    int i;
    s2=malloc(sizeof(s1)*sizeof(char *));
    s2=s1;
    for(i=0;i<sizeof(s2)/sizeof(char *);i  )//for(i=0;i<sizeof(s1)/sizeof(char *);i  )
        printf("%s",*(s2 i));
    return 0;
}
  

Комментарии:

1. Не могли бы вы точно описать, что вы ХОТИТЕ сделать в первую очередь? Кстати, строка s2=malloc(sizeof(s1)*sizeof(char *)); ничего не делает, поскольку вы задаете s2 следующей строкой.

2. @Orka: Я хочу передать адрес s1 в s2, а затем распечатать s2 с помощью цикла for.

Ответ №1:

В прокомментированной строке используется sizeof(char*[4]) , который предположительно в четыре раза больше, чем sizeof(char**) в раскомментированной строке.

Комментарии:

1. итак, я не могу найти размер s2 с помощью sizeof(). Я должен сделать это вручную?

Ответ №2:

При использовании sizeof оператора вы получите размер массива (в байтах). Однако при применении к указателю вы получите размер указателя, а не данные, на которые он указывает.

В C нет способа найти эту информацию, поэтому вы должны управлять этим вручную, например, с помощью size переменной или (как вы уже сделали) использовать размер s1 (который будет работать только до тех пор, пока s1 является массивом).

Ответ №3:

sizeof(s1) выдает общее количество байтов во внешнем массиве, т.е. размер четырех указателей на массивы строк. На моей машине это дает 16 байт (каждый указатель имеет 32 бита). Ваше объявление для s1 эквивалентно выполнению:

 char *s1[4]={"this","is","a","test"};
  

Вы можете сами увидеть эти результаты sizeof:

 printf("sizeof(char[4]) == %dn", sizeof(char*[4])); // == 16
printf("sizeof(char**) == %dn", sizeof(char**)); // == 4
  

Поскольку s2 это символ **, который фактически является символом * с точки зрения sizeof функции, sizeof(s2) дает размер символа *, который на моей машине равен 4 байтам.

Если вы хотите присвоить s2 s1 и распечатать его, попробуйте это:

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

int main(int argc, char* argv[])
{
    char *s1[]={"this","is","a","teeeeeeeeeeest"};
    char **s2;

    s2 = s1;
    int numOfElementsInS1 = sizeof(s1)/sizeof(*s1);
    for(int i = 0; i < numOfElementsInS1; i  )
    {
        printf("s2[%d] = %sn", i, s2[i]);
    }

    return 0;
}
  

…который должен дать:

 s2[0] = this
s2[1] = is
s2[2] = a
s2[3] = teeeeeeeeeeest
  

Если ваша цель здесь — скопировать содержимое s1, тогда вам понадобится что-то вроде этого:

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

int main(int argc, char* argv[])
{
    char *s1[]={"this","is","a","teeeeeeeeeeest"};
    char **s2;

    // Allocate memory for s2 and copy the array contents across
    int numOfElementsInS1 = sizeof(s1)/sizeof(*s1);
    s2 = (char**)malloc(sizeof(s1));
    for(int i = 0; i < numOfElementsInS1; i  )
    {
        size_t bytesInThisString = strlen(s1[i])   1; //   1 for the string termination
        s2[i] = (char*)malloc(bytesInThisString);
        memcpy(s2[i], s1[i], bytesInThisString);
    }

    // Print out s2
    for(int i = 0; i < numOfElementsInS1; i  )
    {
        printf("s2[%d] = %sn", i, s2[i]);
    }

    // Free up the memory
    for(int i = 0; i < numOfElementsInS1; i  )
    {
        free(s2[i]);
    }
    free(s2);

    return 0;
}
  

Ответ №4:

sizeof(s1) … выдает общее количество байтов..

то, что, по вашему мнению, может быть реализовано следующим образом:

 s2=malloc(sizeof(s1)*sizeof(char *));

s2[0] = malloc(sizeof(s1[0])*sizeof(char))
.
.
.
.
n so on