sizeof(table)/ sizof(table [0])无效

时间:2014-02-07 02:15:05

标签: c arrays string char sizeof

我正在用c构建一个基本的shell,我需要知道我填充用户输入的数组的大小。这是代码。

/*
 * Tp1.c
 *
 *  Created on: 25 janv. 2014
 *      Author: shong
 */
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

void cd_handler(int argc, char *argv[]);
int lire(char *chaine, int longueur);
char** init_command(char *str);

int main(int argc, char *argv[]) {

    //printf("La valeur de argc est: %d", argc);
    while(1){
        printf("Log710H2014%>");
        char str[200];
        lire(str, 200);
        char** comms  = init_command(str);
        printf("%s", comms[1]);

        if(strcmp(comms[0], "cd") == 0){
            int commArgsC = sizeof(comms)/sizeof(comms[0]);
            cd_handler(commArgsC, comms);

        }else if (strcmp(comms[0], "exit") == 0){
            exit(0);
        } 
        }
    }
}
void cd_handler(int argc, char *argv[]){
    char cwd[256];
    char * directory;

    if(argc < 2){
        directory  = getenv("HOME");
    }else if (argc == 2){
        directory = argv[1];
    }else{
        exit(1);
    }

    if (chdir(directory) == -1) {
        printf ("chdir failed - %s\n", strerror (errno));
    }else{
        if (getcwd(cwd, sizeof(cwd)) == NULL)
            perror("getcwd() error");
        else
            printf("current working directory is: %s\n", cwd);
    }
}
char** init_command(char* str){
    char ** res  = NULL;
    char *  p    = strtok (str, " ");
    int n_spaces = 0, i;

    while (p) {
        res = realloc (res, sizeof (char*) * ++n_spaces);

        if (res == NULL){
            exit (-1);
        }
        res[n_spaces-1] = p;
        p = strtok (NULL, " ");
    }
    res = realloc (res, sizeof (char*) * (n_spaces+1));
    res[n_spaces] = 0;

    //print the result

    //for (i = 0; i < (n_spaces+1); ++i)
    //printf ("res[%d] = %s\n", i, res[i]);

    //free the memory allocated

    //free (res);
    return res;
}
int lire(char *chaine, int longueur)
{
    char *positionEntree = NULL;

    if (fgets(chaine, longueur, stdin) != NULL)
    {
        positionEntree = strchr(chaine, '\n');
        if (positionEntree != NULL)
        {
            //*positionEntree = '\0'; // On remplace ce caractère par \0
        }
        return 1;
    }
    else
    {
        return 0; // on renvoie 0 s'il y a eu une erreur
    }
}

问题是sizeof(comms)总是返回8,无论comm中的元素数量是多少。

2 个答案:

答案 0 :(得分:5)

comms是一个指针,所以在64位机器上它的大小为8个字节。 C不知道它指向的大小。您必须从分配存储的函数返回大小并自行跟踪它。

答案 1 :(得分:4)

行为sizeof取决于它应用于哪种类型的变量。

如果变量是一个指针,就像在问题中一样,sizeof只是以字节为单位计算指针类型的大小:

int *y;                      //y points to an int... maybe an array? Who knows?
printf("%d",sizeof(y));      //No idea how y has been allocated. Defaults to sizeof(int*)

如果变量声明为数组,sizeof将返回整个数组的大小。例如:

int y[4];                     //y is exactly four ints in memory
printf("%d",sizeof(y));       //sizeof knows this, and evaluates to sizeof(int)*4

这就是sizeof(table)/sizeof(table[0])适用于数组的原因。但是,如上所示,它确实工作指针。简而言之,将数组作为参数传递会破坏有关该数组中数据量的任何信息,并且必须单独传递大小。这被称为“阵列衰减”。

指针和数组之间的区别非常微妙。 99%的时间,两者可以互换使用,并且表现方式完全相同。但是,有两个关键的区别:

  1. 前面讨论的sizeof行为的差异。
  2. 无法将数组指定为指针。这涉及它们具有恒定尺寸的事实。例如:

  3. char **table;
    
    //table can be assigned different values....
    
    table = NULL;
    
    //...multiples times, if wanted
    table = malloc(sizeof(char*)*20);
    

    然而,

    //table is constant
    char *table[20];
    
    //it's individual elements can be assigned as usual...
    table[0] = malloc(1);
    
    //...but attempts to change where table points to will fail
    table = NULL; //This will cause a compilation error.