传递malloced指针时,my struct的值不会更新
我正在为shell实现一个历史记录。我有一个存储命令的结构,这些结构的数组存储历史传递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
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);
}
}