传递malloced指针时,my struct的值不会更新

传递malloced指针时,my struct的值不会更新,c,pointers,C,Pointers,我正在为shell实现一个历史记录。我有一个存储命令的结构,这些结构的数组存储历史 typedef struct command { char **arg; int num; } cmd; 下面的代码正确地更新了历史记录,并打印出来 Cmd#1:ls-l Cmd#1:pwd Cmd#2:ls-l intmain(){ char*参数[3]={“ls”,“-l”,NULL}; cmd*history=startHist(); 历史=更新列表(参数、历史); 印刷历史(历史); c

我正在为shell实现一个历史记录。我有一个存储命令的结构,这些结构的数组存储历史

typedef struct command {
    char **arg;
    int num;
} cmd;
下面的代码正确地更新了历史记录,并打印出来

Cmd#1:ls-l

Cmd#1:pwd

Cmd#2:ls-l

intmain(){
char*参数[3]={“ls”,“-l”,NULL};
cmd*history=startHist();
历史=更新列表(参数、历史);
印刷历史(历史);
char*arg2s[2]={“pwd”,NULL};
历史=更新列表(arg2s,历史);
印刷历史(历史);
自由(历史);
}
cmd*startHist(){
cmd*ret=malloc(20*sizeof(cmd));
对于(int i=0;i0;i--){
hist[i]=hist[i-1];
}
hist[0]。arg=args;
if(hist[1].arg!=NULL){
hist[0]。num=hist[1]。num+1;
}否则{
hist[0].num=1;
}
返回历史;
}
无效打印历史(cmd*hist){
int pos=0;//遍历命令的索引
while(hist[pos].arg!=NULL){
char*prstr=malloc(INIT_BUFFER*sizeof(char));//将要打印的字符串
*prstr='\0';
int index=0;//用于遍历参数的索引
printf(“Cmd#%d:”,pos+1);
while(hist[pos].arg[index]!=NULL){
printf(“%s”,hist[pos].arg[index]);
strcat(prstr,hist[pos].arg[index]);//连接参数字符串
索引++;
}
printf(“\n”);
pos++;
免费(prstr);
}
}
但是,以下代码无法工作。每个cmd条目的字符串值将替换为最新的命令,尽管int值功能正常

编辑:已根据建议修改代码。它现在应该运行3个输入循环。 示例输出:

?:ls

Cmd#1:ls

?:ls-a

Cmd#1:ls-a

Cmd#2:ls-a

?:出口

Cmd#1:退出

命令2:退出

命令3:退出

请注意,startHist()、printHist()和updateHist()与上述内容相同

#include "stdio.h"//get from and print to console
#include "stdlib.h"//free and malloc
#include <string.h>//strtok

//Initial input buffer size. Will be expanded in getLine if needed.
const int INIT_BUFFER = 256;

typedef struct command {
    char **arg;
    int num;
} cmd;

//Function Declarations
char * getLine();//gets the input from the console and returns it
char ** splitLine(char *a);//splits the passed string into argument substrings
cmd* updateHist(char **args, cmd *hist);
void printHist(cmd *hist);
cmd* startHist();

void main() {
    //declare primary variables
    char *input;
    char **args;
    int retVal=3;
    cmd *history = startHist();
    do {//primary execution loop
        printf("?: ");//prompt for input
        input = getLine();
        args = splitLine(input);
        history = updateHist(args, history);
        printHist(history);
        retVal--;
        free(input);
        free(args);
    } while(retVal);
    free(history);
}

char ** splitLine(char *input) {
    //variables for finding the number and length of the arguments
    int numArgs=1;//the number of args in the input(starts at 1, increases per space).
    int pos = 0;//the position as the input is iterated through
    //loop to find the number and length of the arguments
    while(input[pos]!='\0'){//until the end of the input is reached
        if(input[pos]==' '){//if the end of the argument is reached
            numArgs++;//increment argument counter
        }
        pos++;//increment the position counter
    }
    pos=0;//reset pos to reiterate through the input
    //create an array of arguments
    char* *argArray = malloc((1+numArgs)*sizeof(char*));
    char *temp = strtok(input, " \n\r\t");//get the first token from the string
    while(temp!=NULL) {
        argArray[pos] =temp;
        pos++;
        temp=strtok(NULL, " \n\r\t");
    }
    argArray[pos]=NULL;
    return argArray;
}

char * getLine() {
    int buffspace = INIT_BUFFER;
    char *buffer = malloc(sizeof(char)*INIT_BUFFER);
    int pos = 0;
    int c;//input 
    
    if(!buffer) {
        fprintf(stderr, "Shell: Allocation Error\n");
        exit(EXIT_FAILURE);
    }
    
    do {
        c=getchar();//get the next character
        
        if(c==EOF || c=='\n'||c=='\r') {
            buffer[pos]='\0';
            return buffer;
        } else {
            buffer[pos] = c;
        }
        pos++;
        
        if(pos>=buffspace) {
            buffspace += INIT_BUFFER;
            buffer = realloc(buffer, buffspace);
        }
    } while(c!=EOF);
    
    //the buffer should be returned before this point.
    //Print out an error and exit
    fprintf(stderr, "Shell: Assignment Error\n");
    return buffer;
}

cmd* startHist() {
    cmd *ret = malloc(20*sizeof(cmd));
    for(int i=0;i<20;i++){
        ret[i].arg = NULL;
        ret[i].num = -1;
    }
    return ret;
}

cmd* updateHist(char **args, cmd *hist) {
    for(int i = 19;i>0;i--) {
        hist[i] = hist[i-1];
    }
    hist[0].arg = args;
    if(hist[1].arg!=NULL) {
        hist[0].num = hist[1].num+1;
    } else {
        hist[0].num = 1;
    }
    return hist;
}

void printHist(cmd *hist) {
    int pos = 0;//index for iterating through commands
    while(hist[pos].arg!=NULL) {
        char* prstr = malloc(INIT_BUFFER*sizeof(char));//the string that will be printed
        *prstr = '\0';
        int index = 0;//index for iterating through arguments
        printf("Cmd #%d: ", pos+1);
        while(hist[pos].arg[index] != NULL) {
            printf("%s ", hist[pos].arg[index]);
            strcat(prstr, hist[pos].arg[index]);//concatenate the argument strings
            index++;
        }
        printf("\n");
        pos++;
        free(prstr);
    }
}

#包括“stdio.h”//get from和print to console
#包括“stdlib.h”//free和malloc
#包括//strtok
//初始输入缓冲区大小。如果需要,将在getLine中展开。
const int INIT_BUFFER=256;
typedef结构命令{
字符**arg;
int-num;
}cmd;
//函数声明
char*getLine()//从控制台获取输入并返回它
字符**分割线(字符*a)//将传递的字符串拆分为参数子字符串
cmd*updateHist(字符**args,cmd*hist);
无效打印历史(cmd*hist);
cmd*startHist();
void main(){
//声明主变量
字符*输入;
字符**args;
int-retVal=3;
cmd*history=startHist();
do{//主执行循环
printf(“?:”;//提示输入
输入=getLine();
args=分割线(输入);
历史=更新列表(args,history);
印刷史学家(历史);
返回--;
免费(输入);
免费(args);
}while(retVal);
自由(历史);
}
字符**分割线(字符*输入){
//用于查找参数数量和长度的变量
int numArgs=1;//输入中的arg数(从1开始,每个空格增加)。
int pos=0;//迭代输入的位置
//循环以查找参数的数量和长度
while(输入[pos]!='\0'){//,直到到达输入的末尾
if(input[pos]=''){//如果到达参数的末尾
numArgs++;//递增参数计数器
}
pos++;//增加位置计数器
}
pos=0;//通过输入重置pos以重复
//创建一个参数数组
字符**argArray=malloc((1+numArgs)*sizeof(字符*);
char*temp=strtok(输入“\n\r\t”);//从字符串中获取第一个令牌
while(temp!=NULL){
argArray[pos]=温度;
pos++;
temp=strtok(空,“\n\r\t”);
}
argArray[pos]=NULL;
返回argArray;
}
char*getLine(){
int buffspace=INIT_缓冲区;
char*buffer=malloc(sizeof(char)*INIT_buffer);
int pos=0;
int c;//输入
如果(!缓冲区){
fprintf(stderr,“Shell:Allocation Error\n”);
退出(退出失败);
}
做{
c=getchar();//获取下一个字符
如果(c==EOF | | c='\n'| | c=='\r'){
缓冲区[pos]='\0';
返回缓冲区;
}否则{
缓冲器[pos]=c;
}
pos++;
如果(位置>=buffspace){
buffspace+=INIT_缓冲区;
buffer=realloc(buffer,buffspace);
}
}而(c!=EOF);
//缓冲区应在此点之前返回。
//打印出错误并退出
fprintf(stderr,“Shell:Assignment Error\n”);
返回缓冲区;
}
cmd*startHist(){
cmd*ret=malloc(20*sizeof(cmd));
对于(int i=0;i0;i--){
hist[i]=hist[i-1];
}
hist[0]。arg=args;
if(hist[1].arg!=NULL){
hist[0]。num=hist[1]。num+1;
}否则{
hist[0].num=1;
}
返回历史;
}
无效打印历史(cmd*hist){
int pos=0;//遍历命令的索引
while(hist[pos].arg!=NULL){
char*prstr=malloc(INIT_BUFFER*sizeof(char));//将要打印的字符串
*prstr='\0';
int index=0;//用于遍历参数的索引
printf(“Cmd#%d:”,pos+1);
while(hist[pos].arg[index]!=NULL){
printf(“%s”,hist[pos].arg[index]);
strcat(prstr,hist[pos].arg[index]);//连接参数字符串
索引++;
}
printf(“\n”);
pos++;
免费(prstr);
}
}

看起来您只是在
cmd
数据结构中存储指针,而不是指向字符串和数组的指针。这意味着在局部变量超出范围后,您将保存指向它们的指针,这将导致未定义的行为。

看起来您只是将指针存储在
cmd
数据结构中,而不是存储指向
#include "stdio.h"//get from and print to console
#include "stdlib.h"//free and malloc
#include <string.h>//strtok

//Initial input buffer size. Will be expanded in getLine if needed.
const int INIT_BUFFER = 256;

typedef struct command {
    char **arg;
    int num;
} cmd;

//Function Declarations
char * getLine();//gets the input from the console and returns it
char ** splitLine(char *a);//splits the passed string into argument substrings
cmd* updateHist(char **args, cmd *hist);
void printHist(cmd *hist);
cmd* startHist();

void main() {
    //declare primary variables
    char *input;
    char **args;
    int retVal=3;
    cmd *history = startHist();
    do {//primary execution loop
        printf("?: ");//prompt for input
        input = getLine();
        args = splitLine(input);
        history = updateHist(args, history);
        printHist(history);
        retVal--;
        free(input);
        free(args);
    } while(retVal);
    free(history);
}

char ** splitLine(char *input) {
    //variables for finding the number and length of the arguments
    int numArgs=1;//the number of args in the input(starts at 1, increases per space).
    int pos = 0;//the position as the input is iterated through
    //loop to find the number and length of the arguments
    while(input[pos]!='\0'){//until the end of the input is reached
        if(input[pos]==' '){//if the end of the argument is reached
            numArgs++;//increment argument counter
        }
        pos++;//increment the position counter
    }
    pos=0;//reset pos to reiterate through the input
    //create an array of arguments
    char* *argArray = malloc((1+numArgs)*sizeof(char*));
    char *temp = strtok(input, " \n\r\t");//get the first token from the string
    while(temp!=NULL) {
        argArray[pos] =temp;
        pos++;
        temp=strtok(NULL, " \n\r\t");
    }
    argArray[pos]=NULL;
    return argArray;
}

char * getLine() {
    int buffspace = INIT_BUFFER;
    char *buffer = malloc(sizeof(char)*INIT_BUFFER);
    int pos = 0;
    int c;//input 
    
    if(!buffer) {
        fprintf(stderr, "Shell: Allocation Error\n");
        exit(EXIT_FAILURE);
    }
    
    do {
        c=getchar();//get the next character
        
        if(c==EOF || c=='\n'||c=='\r') {
            buffer[pos]='\0';
            return buffer;
        } else {
            buffer[pos] = c;
        }
        pos++;
        
        if(pos>=buffspace) {
            buffspace += INIT_BUFFER;
            buffer = realloc(buffer, buffspace);
        }
    } while(c!=EOF);
    
    //the buffer should be returned before this point.
    //Print out an error and exit
    fprintf(stderr, "Shell: Assignment Error\n");
    return buffer;
}

cmd* startHist() {
    cmd *ret = malloc(20*sizeof(cmd));
    for(int i=0;i<20;i++){
        ret[i].arg = NULL;
        ret[i].num = -1;
    }
    return ret;
}

cmd* updateHist(char **args, cmd *hist) {
    for(int i = 19;i>0;i--) {
        hist[i] = hist[i-1];
    }
    hist[0].arg = args;
    if(hist[1].arg!=NULL) {
        hist[0].num = hist[1].num+1;
    } else {
        hist[0].num = 1;
    }
    return hist;
}

void printHist(cmd *hist) {
    int pos = 0;//index for iterating through commands
    while(hist[pos].arg!=NULL) {
        char* prstr = malloc(INIT_BUFFER*sizeof(char));//the string that will be printed
        *prstr = '\0';
        int index = 0;//index for iterating through arguments
        printf("Cmd #%d: ", pos+1);
        while(hist[pos].arg[index] != NULL) {
            printf("%s ", hist[pos].arg[index]);
            strcat(prstr, hist[pos].arg[index]);//concatenate the argument strings
            index++;
        }
        printf("\n");
        pos++;
        free(prstr);
    }
}