需要认真的帮助 - 我遇到了一个非常奇怪的问题。
我的程序是在库文件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 = ®isters;
或者:
RG_ptr registers = malloc(sizeof(RG));
请记住,如果您使用分配的内存,则需要非常严格地确保所有分配都具有与 free
相应的释放,否则将会泄漏内存。
关于c - C 中变量声明的排列决定了哪一个被执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50092479/