操作内存时是否需要乘以sizeof(char)?

sha*_*oth 15 c malloc memory-management sizeof

当使用malloc并进行类似的内存操作时,我可以依赖sizeof(char)始终为1吗?

例如,我需要为N个元素类型分配内存char.是否sizeof( char )需要乘以:

char* buffer = malloc( N * sizeof( char ) );
Run Code Online (Sandbox Code Playgroud)

或者我可以依赖sizeof(char)始终为1并且只是跳过乘法

char* buffer = malloc( N );
Run Code Online (Sandbox Code Playgroud)

我完全理解sizeof在编译期间进行评估,然后编译器甚至可以编译出乘法,因此性能损失将是最小的并且很可能为零.

我主要询问代码清晰度和可移植性.这种乘法对于类型是否必要char

Dav*_*eau 28

根据定义,sizeof(char)总是等于1.一个字节是C中字符的大小,无论字节中的位数是多少(在普通桌面CPU上为8).

一个字节不是8位的典型示例是PDP-10和其他具有9/36位字节的旧的,类似于微型计算机的架构.但是我相信,不是2 ^ N的字节变得非常罕见

另外,我认为这是更好的风格:

char* buf1;
double* buf2;

buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);
Run Code Online (Sandbox Code Playgroud)

因为它适用于指针类型.

  • @AlexDrenea:今天,您通常只会遇到8位字节.但是字节的定义各不相同,并且与今天的体系结构无关,因为有些系统具有9位字节甚至36位字节.如果您想确定,请使用ISO术语"八位字节"而不是字节. (11认同)
  • 1字节的定义是N位,其中N取决于机器.并非所有机器都有8位/字节(尽管这些天没有那么多) (6认同)

Aam*_*mir 14

sizeof(char) 无论你做什么类型的记忆操作,它总是1.

但是,sizeof(TCHAR)可能会因您的编译器选项而异.

  • @Shadow,没有.在这种情况下,通常使用宽字符类型wchar_t而不是char.特定于Microsoft的TCHAR业务是一种编写可以为宽字符或窄字符编译的代码的方法.目前尚不清楚这是否是一个好主意. (4认同)

unw*_*ind 11

我认为这是一种反模式.它表明程序员并不完全知道他/她在做什么,这会立即将其余的代码置于可疑的角度.

当然,它不是(引用维基百科)"无效",但我发现它"远非最佳".它在运行时没有花费任何成本,但它使代码混乱不必要的垃圾,同时发出信号,有人认为这是必要的.

另请注意,表达式不会解析为函数调用:sizeof不是函数.你不是在称一个函数传递它的神奇符号char.您正在将一个内置的一元前缀运算符sizeof应用于表达式,并且您的表达式在这种情况下是对该类型的强制转换char,在C中将其写为(char).

完全可能,并且强烈建议尽可能使用sizeof其他表达式,然后它将产生表达式值的大小:

char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);
Run Code Online (Sandbox Code Playgroud)

这将1始终打印在所有符合C的实现上.

我还积极与大卫Cournapeau同意并考虑重复类型名称malloc()-call来成为一种反模式的.

代替

char *str;

str = malloc(N * sizeof (char));
Run Code Online (Sandbox Code Playgroud)

许多人会写,以分配一个N字符容量的字符串缓冲区,我会去

char *str;

str = malloc(N * sizeof *str);
Run Code Online (Sandbox Code Playgroud)

或者(仅限字符串)省略sizeof如上所述,但这当然更通用,并且适用于任何类型的指针.

  • 我不同意.如果省略它(以及任何阅读代码的人)必须记住这是一个特殊情况,并将其识别出来.这增加了认知负担.有时更多代码更好. (2认同)
  • @Michael Carman - 通常_is_是一个特殊情况,因为你经常分配和使用字符串,而如果你创建一个int数组,它可以用于任何目的.我们需要处理字符串的方式与任意类型的数组不同,我发现`malloc()`中缺少`sizeof(type)`是一个很好的提醒. (2认同)

Mat*_*och 6

没有必要.见这里(例如).

sizeof(char)由C标准定义为始终为1(字节).请注意,因为sizeof返回多个字节,每个字节的位数无关紧要(实际上,无论如何都是8).


mnu*_*zzo 6

虽然没有必要,但我认为留下sizeof(char)是一种好习惯,因为它使代码更具可读性并避免使用幻数.此外,如果稍后需要更改代码,那么代替char将某些内容的大小拼接成该对象的指针,与仅使用"1"相比,更改代码更容易.

  • 这种"易于改变代码"的论点是公牛.`sizeof()`是8个字符.必须添加它,因为有人没有写'sizeof(char)`然后类型改为`wchar_t`将不会给任何人腕管,如果你担心这个你应该使用`sizeof*buf`无论如何因为它甚至可以节省你_less_打字. (8认同)
  • @Shahbaz - 6.5.3.4第4段:"当`sizeof`应用于具有类型`char`,`unsigned char`或`signed char`(或其合格版本)的操作数时,结果为1." 因此它一直是,因此它将永远是.`char`是C的"字节".从语言的角度来看,`char`是多少位无关紧要,它是最小的完整单元,所有`sizeof`值都以`char'给出`s而不是"bytes"(在C标准中没有正确存在).如果所有类型都是64位,`sizeof(char)== sizeof(short)== sizeof(int)== sizeof(long)== 1`,而不是8. (4认同)