在C语言中,何时分配内存?

4

我有下面的代码,它应该将一个字节内的位的位置移动。它可以工作,但我的问题与其他事情有关。

关于example_bytenew_byte的分配,我做错了什么,又做对了什么?这个简单的程序是否太麻烦了?我是否应该不使用malloc,让编译器更好地完成这项工作?

这里有个人在评论区发表了他的看法:link

#include <stdio.h>
#include <malloc.h>

typedef unsigned __int8 byte;

byte move(byte* our, int indexold, int indexnew)
{
byte oldvalue;
byte newvalue;
byte valuetochange;

valuetochange = 0x01 & ((*our)>>indexold);         // get the value of the bit to be moved
printf("value to change : %d\n", valuetochange);
oldvalue = (*our) & (~(1<<(indexold)));            // del the bit from position indexold
oldvalue = oldvalue & (~(1<<(indexnew)));          // del the bit from position indexnew
printf("deleted: %x\n", oldvalue);

newvalue = oldvalue | (valuetochange<<(indexnew)); // write bit in new position (indexnew)

return newvalue;
}

int main()
{
byte* example_byte;
byte* new_byte;

example_byte = (byte*)malloc(sizeof(byte));
new_byte     = (byte*)malloc(sizeof(byte));

*example_byte = 0xc3;  //  hex 0xc3 = binary 1100 0011
printf("\n");

//*****************************************************
// example 1 (move bit from position 1 to position 5)
// example_byte  1100 0011
//                 ^    ^
//               memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 1
//               1100 0011 & 1111 1101 = 1100 0001 delete bit from oldindex (1)
//               1100 0001 & 1101 1111 = 1100 0001 delete bit from newindex (5)
// new_byte      1100 0001 | 0010 0000 = 1110 0001
*new_byte     = move(example_byte, 1, 5);

printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x\n", *new_byte);     // 0xe1 (1110 0001)
printf("\n");

//*****************************************************
// example 2 (move bit from position 6 to position 3)
// example_byte  1100 0011
//                ^   ^
//               memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 1
//               1100 0011 & 1011 1111 = 1000 0011 delete bit from oldindex (6)
//               1000 0011 & 1111 0111 = 1000 0011 delete bit ftom newindex (3)
// new_byte      1000 0011 | 0000 1000 = 1000 1011
*new_byte     = move(example_byte, 6, 3);

printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x\n", *new_byte);     // 0x8b (1000 1011)
printf("\n");

//*****************************************************
// example 3 (move bit from position 2 to position 6)
// example_byte  1100 0011
//                ^    ^
//               memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 0
//               1100 0011 & 1111 1011 = 1100 0011 delete bit from oldindex (2)
//               1100 0011 & 1011 1111 = 1000 0011 delete bit from oldindex (6)
// new_byte      1000 0011 | 0000 0000 = 1000 0011
*new_byte     = move(example_byte, 2, 6);

printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x\n", *new_byte);     // 0x83 (1000 0011)
printf("\n");

//*****************************************************
// example 4 (move bit from position 2 to position 4)
// example_byte  1100 0011
//                  ^  ^
//               memorize bit -> valuetochange = 0x01 & ((*our)>>indexold) = 0
//               1100 0011 & 1111 1011 = 1100 0011 delete bit from oldindex (2)
//               1100 0011 & 1110 1111 = 1100 0011 delete bit from oldindex (4)
// new_byte      1100 0011 | 0000 0000 = 1100 0011
*new_byte     = move(example_byte, 2, 4);

printf("old byte : %x\n", *example_byte); // 0xc3 (1100 0011)
printf("new byte : %x  ", *new_byte);     // 0xc3 (1100 0011)
printf("\n");

free(new_byte);
free(example_byte);
return 0;
}

这似乎是一个适合在http://codereview.stackexchange.com/上提问的问题。 - Dima
1
你需要决定你是使用C还是C++。尽管它们在语法上很相似,但实际上它们是有着不同的范式和风格的完全不同的语言。在C中的良好实践,在C++中常常被人所反对,反之亦然。 - sbi
1
@sbi:在C语言中,“C++的良好实践”不仅不会被看作是不好的,而且根本就不可能存在 :) - Billy ONeal
1
@Billy:是的,当然,但那些C开发人员仍然对我们的做事方式表示不满!:) - sbi
3个回答

13

只有在需要引用超出您声明其范围以及嵌套在其中的任何范围之外的内容,或者需要动态分配内存以创建未知大小的数据结构时,才需要分配内存。否则,您应该只声明一个本地变量。


2
如果您将int类型作为函数返回值,则可以在函数中创建的int变量中使用它。是的,这将使用其副本,那又怎样?在C++中,您也可以对string类型做同样的事情,在C中则不行。这就是为什么将其标记为C和C ++是愚蠢的原因。 - sbi
或者,如果堆栈的内存太大,尝试在堆栈中分配30MB的内存,根据您的系统,可能会出现堆栈溢出。 - fbafelipe

8
如果只有一个字节,就没有必要进行内存分配。你可以声明一个类型为byte的本地变量并传递它。
当你需要分配一个元素数组且在编译时不知道元素数量时,需要使用malloc()。当你需要分配一个大型结构体并希望其在创建它的函数退出后仍然存在于内存中时,也需要使用它。如果你处理的是原始类型的变量,则应将其声明为本地变量,这意味着它将自动在堆栈上分配。

3

正如Dima所提到的:只需使用一个字节,并使用&运算符将其地址传递给move函数。

byte example_byte;
byte new_byte;

example_byte = 0xc3;  //  hex 0xc3 = binary 1100 0011
new_byte     = move(&example_byte, 1, 5);

您可以将move(...)的参数类型更改为byte,这样使用起来会更加容易。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接