Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么我的动态2D字符数组中的值会被覆盖?_C_Arrays_Linux_Dynamic_Realloc - Fatal编程技术网

C 为什么我的动态2D字符数组中的值会被覆盖?

C 为什么我的动态2D字符数组中的值会被覆盖?,c,arrays,linux,dynamic,realloc,C,Arrays,Linux,Dynamic,Realloc,我正试图在Linux上用C语言构建一个进程记录器,但在正确使用它时遇到了困难。我希望它有3列:用户、PID、命令。我正在使用ps aux的输出,并尝试将其动态附加到数组中。也就是说,对于每一行ps aux输出,我想在数组中添加一行 这是我的密码。(为了保持输出简短,我只对sublime进行grep。但这可以是任何内容。) 但是,从put(line)我得到数组实际上应该包含以下内容: user 5016 sh -c ps -eo user,pid,command --sort %cpu

我正试图在Linux上用C语言构建一个进程记录器,但在正确使用它时遇到了困难。我希望它有3列:用户、PID、命令。我正在使用
ps aux
的输出,并尝试将其动态附加到数组中。也就是说,对于每一行
ps aux
输出,我想在数组中添加一行

这是我的密码。(为了保持输出简短,我只对sublime进行grep。但这可以是任何内容。)

但是,从
put(line)
我得到数组实际上应该包含以下内容:

user       5016 sh -c ps -eo user,pid,command --sort %cpu | grep sublime
user       5018 grep sublime
user      27184 /opt/sublime_text/sublime_text
user      27194 /opt/sublime_text/plugin_host 27184
所以,显然所有的值都被覆盖了,我不明白为什么。。。(另外,我不知道
进程[0]=7194
进程[4]=7194
中的值
7194
来自何处)

我做错了什么?是否有可能使输出看起来像
put(line)
的输出


任何帮助都将不胜感激

strtok
将指针返回到它处理的字符串中。该字符串始终存储在变量
中。因此,数组中的所有指针都指向内存中的同一位置


正如@Lundin在评论中所写,这里没有二维数组,只有一维指针数组。

strok的返回值是指向您标记的字符串的指针。(通过使用
'\0'
覆盖标记后面的第一个分隔符,标记已被设为null终止)

当您使用
fgets
读取新行时,您将覆盖此行的内容,并且所有标记(不仅仅是上次解析中的标记)都指向该行的实际内容。(指向前面标记的指针仍然有效,但这些位置的内容会更改。)

有几种方法可以解决这个问题

  • 您可以使令牌保存字符数组和
    strcpy
    解析内容
  • 您可以使用(非标准的)
    strdup
    复制解析后的令牌,它为堆上的字符串分配内存
  • 您可以读取一个行数组,这样令牌就真的是唯一的了

此处没有2D阵列。您有一个一维指针数组。对于每个指针,分配一块内存并将读取子字符串复制到那里。感谢您的帮助!我尝试了
strdup
方法,效果很好!还有一个问题:在执行时间方面,最快的方法是什么?很难说哪种方法最快。重复分配需要一些时间(因此,您为每个字符串重新分配
进程
的速度应该很慢),但在您的示例中,我认为外部调用对性能的影响比存储字符串的方式更为重要。
strdup
变量当然是最灵活的方法,但请记住以后要
释放
重复的字符串。我应该在哪里释放重复的字符串?在while循环之后(就像
free(进程)
)?是否有替代
popen()
ps
的方法来提高性能?也许不使用外部调用?在您的情况下,您应该在释放包含数组之前释放字符串,
进程
。请记住,在释放
进程后,其内容不再有效,因此您必须在释放之前执行此操作。销毁(
free
)的创建顺序与之相反(
malloc
)。一般来说,当你不再需要的时候,你可以释放一些东西,这通常是在函数的末尾。建立一个稳定的、可理解的程序。只有在表演糟糕的时候,你才应该开始调查。
processes[0] = user
processes[1] = 7194
processes[2] = /opt/sublime_text/plugin_host 27184

processes[3] = user
processes[4] = 7194
processes[5] = /opt/sublime_text/plugin_host 27184

processes[6] = user
processes[7] = 27194
processes[8] = /opt/sublime_text/plugin_host 27184

processes[9] = user
processes[10] = 27194
processes[11] = /opt/sublime_text/plugin_host 27184
user       5016 sh -c ps -eo user,pid,command --sort %cpu | grep sublime
user       5018 grep sublime
user      27184 /opt/sublime_text/sublime_text
user      27194 /opt/sublime_text/plugin_host 27184