在main外部和Inside main内部分配全局结构变量

时间:2018-10-19 18:26:54

标签: c struct main

问题是当我将代码分成不同的函数时会发生这种情况

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

//------Options -- change only true / false to trigger the function
bool hard_trace = false;
bool trace = true;
/*-------------------*/

//---------Defines----------
#define MAXSIZE 100 // maximum size of the characters in txt file to be buffed
/*----------------------*/

//---------Structs-----------
struct Matrix
{
    char *A[10];
    int depth;
};
/*--------------------------*/
//-----Variable----------
//-- global
char *B[3];
//- struct
struct Matrix matrixs ; // create new global struct
//-
//--
/*-----------------------*/

int convertCharToNumber(char target[1])
{
    int numbered = target[0] - 48;
    return numbered;
}

int generateDataFromFile(){
    //-- temped
    int currentLine = 1;
    int currentRow = 0;
    //-----------------
    FILE *fp;
    char line[MAXSIZE];

    fp = fopen("test.txt", "r");
    if (fp == NULL)
    {
        fprintf(stderr, "%s\n", "Error reading from file");
        exit(EXIT_FAILURE);
    }

    while (fgets(line, MAXSIZE, fp) != NULL)
    {
        if(hard_trace){ // if it was enabled
            printf("current line : %d and length : %d\n", currentLine, strlen(line));
        }
        if (line[strlen(line) - 1] == '\n') // cutout the \n to make the txt easy to use
        {
            line[strlen(line) - 1] = '\0';
        }
        //appileToStruct(line,currentRow);
        matrixs.A[currentRow] = line;
        //if(trace) printf("%s\n", line);
        currentLine++; currentRow++;
    }
    if(trace) printf("Total line receive from txt file : %d\n" , currentLine-1); //if it was enabled
    fclose(fp);

    // ----------- assign the var
    matrixs.depth = currentLine - 1;
    //----------------------------

    //return 1;
}

void main(){
    generateDataFromFile();
    printf("Total : %d TXT : [%s]", strlen(matrixs.A[0]), matrixs.A[0]);
}

以及此处的输出

从txt文件接收的总行数:3

总数:10 TXT:[]

但是当我直接将代码放在这样的主体中

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

//------Options -- change only true / false to trigger the function
bool hard_trace = false;
bool trace = true;
/*-------------------*/

//---------Defines----------
#define MAXSIZE 100 // maximum size of the characters in txt file to be buffed
/*----------------------*/

//---------Structs-----------
struct Matrix
{
    char *A[10];
    int depth;
};
/*--------------------------*/
//-----Variable----------
//-- global
char *B[3];
//- struct
struct Matrix matrixs; // create new global struct
//-
//--
/*-----------------------*/

int convertCharToNumber(char target[1])
{
    int numbered = target[0] - 48;
    return numbered;
}

int main()
{
    //-- temped
    int currentLine = 1;
    int currentRow = 0;
    //-----------------
    FILE *fp;
    char line[MAXSIZE];

    fp = fopen("test.txt", "r");
    if (fp == NULL)
    {
        fprintf(stderr, "%s\n", "Error reading from file");
        exit(EXIT_FAILURE);
    }

    while (fgets(line, MAXSIZE, fp) != NULL)
    {
        if (hard_trace)
        { // if it was enabled
            printf("current line : %d and length : %d\n", currentLine, strlen(line));
        }
        if (line[strlen(line) - 1] == '\n') // cutout the \n to make the txt easy to use
        {
            line[strlen(line) - 1] = '\0';
        }
        //appileToStruct(line,currentRow);
        matrixs.A[currentRow] = line;
        //if(trace) printf("%s\n", line);
        currentLine++;
        currentRow++;
    }
    if (trace)
        printf("Total line recieve from txt file : %d\n", currentLine - 1); //if it was enabled
    fclose(fp);

    // ----------- assign the var
    matrixs.depth = currentLine - 1;
    //----------------------------

    printf("Total : %d TXT : [%s]", strlen(matrixs.A[0]), matrixs.A[0]);
}

输出

从txt文件接收的总行数:3

总计:10 TXT:[0000111100]

您能向我解释为什么第一个代码不起作用吗,我的意思是为什么printf中的%s不能为我显示输出以及我如何才能使第一个代码正常工作

2 个答案:

答案 0 :(得分:0)

这就是原因:matrixs.A[currentRow] = line;

line在第一种情况下是该函数的本地函数。该语句分配了指针,它不会复制字符串(您应该使用strncpy,并且不要忘记通过malloc 分配所需的内存空间),因此当一切都在main()中,line在该范围内得到了很好的定义,因此matrixs.A[0]是指向现有line的指针,而在第一种情况下,行是属于的本地数组generateDataFromFile()。

当您尝试从matrixs.A[0]打印main()时(在第一种情况下),您会调用未定义的行为,因为您正在执行违反堆栈的行为并尝试访问堆栈上的某个地址,该地址可能包含流程执行时所需的任何内容。

建议的解决方法:

// instead of matrixs.A[currentRow] = line
size_t lineSize = strlen(line)+1;
matrixs.A[currentRow] = malloc(lineSize);
strncpy(matrixs.A[currentRow], line, lineSize);

别忘了最后free()分配的内存。

答案 1 :(得分:0)

执行此操作时:

matrixs.A[currentRow] = line;

您正在将本地数组line的地址分配给matrixs.A的元素。在第二个程序的情况下,由于line仍在作用域内,因此它会打印有效值。但是在第一个程序中,line超出范围,因此matrixs.A[0]指向无效的内存。取消引用此指针将调用undefined behavior

此外,在第二个程序中,您可能会注意到matrixs.A的每个元素都包含您读取的最后一个值。再次是因为您要在每个地址中存储line的地址。

您应该对所读取的字符串进行复制,并保存指向新字符串的指针。这样,1)您没有存储局部变量的地址,2)您没有在matrixs.A的每个元素中存储相同的地址。

matrixs.A[currentRow] = strdup(line);