c - C 中变量声明的排列决定了哪一个被执行?

标签 c pointers struct declaration

需要认真的帮助 - 我遇到了一个非常奇怪的问题。

我的程序是在库文件Test.h中定义不同结构的程序。这是 Test.h 文件:

typedef struct InstructionFields{ 
  unsigned int op;         /* opcode: bits 31-26 */
  unsigned int rs;         /* first register source operand: bits 25-21 */
  unsigned int rt;         /* second register source operand: bits 20-16 */
  unsigned int rd;          /* destination register: bits 15-11 */
  unsigned int shamt;      /* shift amount: bits 10-6 */
  unsigned int immedOrAddress;      /* constant or address: bits 15-0 */ 
  unsigned int target;    /* jump target: bits 25-0 */
  unsigned int funct;      /* function: bits 5-0 */
} IF, *IF_ptr;

typedef struct ControlSignalsList{ 
  unsigned int RegDst;         /* Register Destination */
  unsigned int RegWrite;         /* Write Register */
  unsigned int ALUSrc;         /* ALU Source */
  unsigned int MemRead;      /* Mem Read */
  unsigned int MemWrite;      /* Mem Write */ 
  unsigned int MemtoReg;      /* Memory to Register*/
  unsigned int ALUControl ;    /*4 bit ALU control */
  unsigned int Branch;         /* BEQ */
  unsigned int Jump;          /* Jump*/
} CS, *CS_ptr;

typedef struct RegisterStructure{ 
  int t0;         /* Register t0 */
  int t1;         /* Register t1 */
  int t2;         /* Register t2 */
  int t3;         /* Register t0 */
  int ReadData1;      /* Read Data 1 buffer */
  int ReadData2;      /* Read Data 2 buffer */ 
  int WriteReg; 
  unsigned int readReg1;   /* address of rs */
  unsigned int readReg2;   /* address of rt */
   /* WriteReg */
} RG, *RG_ptr;

typedef struct ALUStructure{
  int DataOut;
  unsigned int Zero;
} AS, *AS_ptr;

接下来,文件 Test.c 包含此库,声明使用这些结构的变量,然后将值分配给结构的不同字段。

这是Test.c文件:

#include "Test.h"
#include <stdio.h>

int main() {
 CS_ptr controlSignals;         // Line 5
 IF_ptr iFields;                // Line 6
 RG_ptr registers;              // Line 7 
 AS_ptr as;                     // Line 8

 controlSignals->RegDst = 0;    // Line 11
 //registers->t0 = 0;           // Line 12
 //iFields->op = 0;             // Line 13
 //as->DataOut = 0;             // Line 14

 printf("This is fine\n");
return 0;
}

上面的代码工作正常。但是,一旦我取消第 12 行的注释,就会出现段错误:Segmentation failure: 11。我使用了 valgrind,这是错误消息:

==2002== Use of uninitialised value of size 8
==2002==    at 0x100000F5A: main (test.c:11)
==2002== 
==2002== Use of uninitialised value of size 8
==2002==    at 0x100000F64: main (test.c:12)
==2002== 
==2002== Invalid write of size 4
==2002==    at 0x100000F64: main (test.c:12)
==2002==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

==2002== Process terminating with default action of signal 11 (SIGSEGV)
==2002==  Access not within mapped region at address 0x0
==2002==    at 0x100000F64: main (test.c:12)
==2002==  If you believe this happened as a result of a stack
==2002==  overflow in your program's main thread (unlikely but
==2002==  possible), you can try to increase the size of the
==2002==  main thread stack using the --main-stacksize= flag.
==2002==  The main thread stack size used in this run was 8388608.

一开始我以为是指针未初始化的问题,所以我将指针初始化为NULL。但它并没有解决任何问题,甚至还造成了更多的段错误。所以我就不管他们了。

然后,我尝试移动东西。奇怪的是,如果我将第 7 行移到第 5 行之前的顶部(首先声明 RG_ptr),并取消注释第 11 行,则执行 registers->t0 = 0 ,并且段错误已修复!

同样的事情也发生在其他指针声明上。仅当指针声明位于开头时,才会执行相应的字段赋值。任何其他字段分配在未注释时都会导致段错误。

这是怎么回事?如何解决这个问题?我感谢任何帮助!

最佳答案

有问题的代码是:

RG_ptr registers;
registers->t0 = 0;

请注意,RG_ptr 是一个指针,并且它从未初始化。使用未初始化的指针是未定义的行为,并且您的程序会崩溃。

NULL 指针实际上并未“初始化”。这只会产生一个空指针,并且指向无效内存。您也无法在不崩溃的情况下取消引用该指针。通常人们使用空指针来指示“未分配”或“不相关”的内容,而不是未初始化,这意味着指针可能包含垃圾数据。

您必须通过分配内存或将其指向现有的 RG 结构来初始化该指针。

例如:

RG registers;
RG_ptr registers_pointer = &registers;

或者:

RG_ptr registers = malloc(sizeof(RG));

请记住,如果您使用分配的内存,则需要非常严格地确保所有分配都具有与 free 相应的释放,否则将会泄漏内存。

关于c - C 中变量声明的排列决定了哪一个被执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50092479/

相关文章:

c++ - 长双字面量的 C++ 后缀是什么?

c++ - 指向具有显式构造函数的对象的指针

c - 使用 MPI 的 C 语言结构数组

c - 指针指的是物理内存还是虚拟内存?

c - 如何在我的 cuda 代码中使用 opencv?

C 使用 open()read()write() 访问文本修改它并存储在一个新文件中

C - 我可以在结构中定义默认函数指针吗?

ios - Swift 中指针的替代品?

c++ - 获取父结构体的成员

c - 'typedef in C' 有什么用?