为啥当前节点中的int字段与链表中下一个节点的字符串字段相同?

Posted

技术标签:

【中文标题】为啥当前节点中的int字段与链表中下一个节点的字符串字段相同?【英文标题】:Why does the int field in the current node is the same as the string field at the next node in linked lists?为什么当前节点中的int字段与链表中下一个节点的字符串字段相同? 【发布时间】:2021-10-14 23:56:18 【问题描述】:

我正在编写一个使用链表保存信息的程序,这是头文件中结构体的定义。

结构.h:

typedef struct node* symbolPtr;

/* this will represent a member in the symbol table */
typedef struct node 
    char name[32];
    int address;
    
    symbolPtr next;
 Symbol;

而且我注意到'address'字段的地址与下一个节点中的'name'字段的地址相同,我不明白为什么。

这是主文件 assembler.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "structures.h"


int firstRound(FILE*, symbolPtr, int*, int*);

int main() 
    FILE *file;
    int i;
    int *IC, *DC;
    symbolPtr smblTable;
    
    IC = malloc(sizeof(int));
    DC = malloc(sizeof(int));
    
    smblTable = malloc(sizeof(Symbol));
    
    smblTable->name[0] = '\0';
    smblTable->next = NULL;
    
    
    file = fopen("a.as", "r");
        
    

    firstRound(file, smblTable, IC, DC);
    
    free(IC);
    free(DC);
    free(smblTable);
    return 0;

这是发生问题的文件,firstMove.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "structures.h"

static int addToSmblTable(char*, symbolPtr, int);
static void printAd(symbolPtr smblTable);

int firstRound(FILE *file, symbolPtr smblTable, int *IC, int *DC) 
    char checker[32];
    
    *IC = 100, *DC = 0;

    /* this will go until we reach the end of the file */
    for (; !feof(file);) 
        fscanf(file, "%s", checker);
        
        addToSmblTable(checker, smblTable, *DC);//this saves the value of *DC in the node
        (*DC)++;
    
    
    printAd(smblTable);// prints all the values of the linked list at the end
    
    return 0;


static void printAd(symbolPtr smblTable) 
    symbolPtr node;
    
    for (node = smblTable; node->next; node = node->next) 
        printf("\n%s:   %p  %p  %d\n", node->name, node->next->name, &(node->address), node->address);
//prints the string, the address of the next string and the address of the current 'address' field.
    



static symbolPtr getLastNode(char *, symbolPtr);


static int addToSmblTable(char *symbol, symbolPtr table, int address) 
    symbolPtr node;
    
    
    
    node = getLastNode(symbol, table);//the last node
    
    if (node->name[0] != '\0') 
        node->next = malloc(sizeof(symbol));
        node = node->next;
    
    
    /* saving the symbol */
    
    strcpy(node->name, symbol);//here the address of the last node is being changed
    node->address = address;
    
    
    
    node->next = NULL;
    
    
    return 0;



static symbolPtr getLastNode(char *symbol, symbolPtr table) 
    symbolPtr node;
    
    /* going over the symbol table and checking for the symbol */
    node = table; 
    while (node->next) 
        node = node->next;
    
    
    return node;

这是ma​​kefile:

test: assembler.o firstMove.o syntax.h structures.h
    gcc -g -ansi -Wall -pedantic assembler.o firstMove.o -o test

assembler.o: assembler.c structures.h
    gcc -c -g -ansi -Wall -pedantic assembler.c -o assembler.o

firstMove.o: firstMove.c structures.h
    gcc -c -g -ansi -Wall -pedantic firstMove.c -o firstMove.o

假设这是 a.as:

;file

;sample

.entry

.extern 

STR:

MAIN:

LOOP:

la

jmp

Next:

LIST:

bgt

la

sw

bne

call

jmp

la

.extern

.dh

K:

END:

.entry

那么这是输出:

In file a.as:

;file:  0x5566c6197920  0x5566c6196300  0

;sample:    0x5566c6197940  0x5566c6197940  1953391918

.entry: 0x5566c6197960  0x5566c6197960  1954047278

.extern:    0x5566c6197980  0x5566c6197980  978474067

STR::   0x5566c61979a0  0x5566c61979a0  1313423693

MAIN::  0x5566c61979c0  0x5566c61979c0  1347374924

LOOP::  0x5566c61979e0  0x5566c61979e0  24940

la: 0x5566c6197a00  0x5566c6197a00  7368042

jmp:    0x5566c6197a20  0x5566c6197a20  1954047310

Next::  0x5566c6197a40  0x5566c6197a40  1414744396

LIST::  0x5566c6197a60  0x5566c6197a60  7628642

bgt:    0x5566c6197a80  0x5566c6197a80  24940

la: 0x5566c6197aa0  0x5566c6197aa0  30579

sw: 0x5566c6197ac0  0x5566c6197ac0  6647394

bne:    0x5566c6197ae0  0x5566c6197ae0  1819042147

call:   0x5566c6197b00  0x5566c6197b00  7368042

jmp:    0x5566c6197b20  0x5566c6197b20  24940

la: 0x5566c6197b40  0x5566c6197b40  1954047278

.extern:    0x5566c6197b60  0x5566c6197b60  6841390

.dh:    0x5566c6197b80  0x5566c6197b80  14923

K:: 0x5566c6197ba0  0x5566c6197ba0  977555013

END::   0x5566c6197bc0  0x5566c6197bc0  1953391918

.entry: 0x5566c6197be0  0x5566c6197be0  1953391918

并且可以看到每个'address'字段的地址与下一个节点中'name'字段的地址相同。

这是为什么呢?我没有正确分配结构内存吗?

【问题讨论】:

OT:指针 typedef 只是 IMO 的一大禁忌 OT:不要投 malloc a.as !?嗯.. printf("\nIn file %s:\n", argv[i]); 嗯...未初始化i 你想看***.com/q/5431941/4386427 【参考方案1】:

考虑一下这是在做什么

node->next = malloc(sizeof(symbol));

这里分配了多少字节? symbol 是什么?

好的:

static int addToSmblTable(char *symbol, symbolPtr table, int address) 
    symbolPtr node;
    
    node = getLastNode(symbol, table);//the last node
    
    if (node->name[0] != '\0') 
        node->next = malloc(sizeof(symbol));

所以symbolchar*。您确定要为 char 指针分配内存吗?

这可能是一个简单的错字吗? symbol -> Symbol

更好的方法是:

node->next = malloc(sizeof *(node->next));

【讨论】:

32 + int 的大小? @SagiSason 再次阅读答案的最后一行 @SagiSason symbolSymbol 非常感谢!我不敢相信这一直是这个错字.... @SagiSason 我不敢相信你决定给一个字符指针命名为symbol。这不是Symbol - 它是一个文本字符串。所以就这样称呼它,避免简单的错别字;-)

以上是关于为啥当前节点中的int字段与链表中下一个节点的字符串字段相同?的主要内容,如果未能解决你的问题,请参考以下文章

数组与链表的优缺点

判断单向链表是否有环,以及环入口与链表头节点的距离

1030.链表中下一个最大的节点

数组链表的概念及区别

4链表

将第一个节点添加到hashmap中的链表时,为啥必须将新节点直接分配给索引指针?