使用system遇到的坑

最近工作中由于需要在C中调用shell脚本,在C中调用shell脚本可以使用popen或者system来实现,我选择库函数system来调用shell脚本,但是使用过程中遇到了问题,调用库函数system总是返回-1,shell脚本总是无法执行,这百思不得其解,man其函数简介:
SYSTEM(3)                                     Linux Programmer's Manual               SYSTEM(3)
NAME
       system - execute a shell command
SYNOPSIS
       #include <stdlib.h>
       int system(const char *command);
DESCRIPTION
       system()  executes  a  command  specified  in  command by calling /bin/sh -c command, and returns after the command has been completed.  During execution of the command, SIGCHLD will be
       blocked, and SIGINT and SIGQUIT will be ignored.
RETURN VALUE
       The value returned is -1 on error (e.g.  fork(2) failed), and the return status of the command otherwise.  This latter return status is in the format specified in  wait(2).   Thus,  the
       exit code of the command will be WEXITSTATUS(status).  In case /bin/sh could not be executed, the exit status will be that of a command that does exit(127).
       If the value of command is NULL, system() returns nonzero if the shell is available, and zero if not.
       system() does not affect the wait status of any other children.

其中SYSTEM(3),其中的3代表是库函数,2代表系统调用,1代表可执行程序或者shell命令。
从其man简介来看,返回-1主要是因为fork子进程失败。那什么导致fork子进程失败呢?这为什么会fork失败,这问题也花费了好长时间,后面使用使用strerrno(errno)打印出错误原因:Cannot allocate memory,没有内存导致的,原来调用system的进程会使用很大的内存,而fork出的子进程在写时会拷贝父进程的内存空间,系统剩余的内存有限,这导致申请不到内存,从而导致fork失败,最终导致执行system函数失败。所以使用system要注意父进程使用的内存空间及系统是剩余内存空间。  
至于怎么解决该问题?可以自己实现一个类似的system函数,里面不调用fork,调用vfork函数来实现,当然这是有限制的。  
建议:1.对于库函数和系统调用函数,使用前最好先了解其是怎么样使用的,使用时应该注意什么,个人认为阅读man函数解决就可以了,如果还是不太了解,再网上找相关资料。  
2.调用出现错误,最好打出其错误号和错误原因,errno和strerror(errno)要利用起来,这样能提供解决问题的效率。
当我们在使用快速排序算法实现时,经常遇到一些常见的问题。下面是一些填法的建议: 1. 选择合适的基准元素:快速排序的关键是选择一个基准元素,并将数组分为两个子数组。一个常见的选择是将第一个元素作为基准,但在某些情况下,这可能导致性能下降。为了避免最坏情况的出现,可以考虑使用随机选择或选取中间值作为基准。 2. 处理相等元素:快速排序通常使用双指针法将元素分为两个子数组。但如果数组中存在相等的元素,可能导致分割不均衡,从而影响排序的效率。一种解决方法是使用三路快速排序,在基准元素的基础上再增加一个指针,将数组分为小于、等于和大于基准的三个部分。 3. 处理递归边界:快速排序使用递归来排序子数组。在实现递归函数时,需要确保处理边界情况,避免无限递归或越界错误。通常情况下,当子数组只有一个元素或为空时,可以作为递归的终止条件。 4. 优化递归次数:在某些情况下,快速排序可能导致递归层数过深,消耗大量的栈空间。为了避免这种情况,可以考虑使用迭代的方式来实现快速排序,使用栈来保存待处理的子数组。 下面是一个使用法实现快速排序的Java示例代码: ```java public class QuickSort { public void quickSort(int[] nums, int low, int high) { if (low < high) { int pivotIndex = partition(nums, low, high); // 获取基准元素的位置 quickSort(nums, low, pivotIndex - 1); // 对基准元素的左边子数组进行排序 quickSort(nums, pivotIndex + 1, high); // 对基准元素的右边子数组进行排序 } } private int partition(int[] nums, int low, int high) { int pivot = nums[low]; // 选择第一个元素作为基准 int left = low + 1; int right = high; while (true) { while (left <= right && nums[left] < pivot) { left++; } while (left <= right && nums[right] > pivot) { right--; } if (left > right) { break; } // 交换左指针和右指针所指向的元素 int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; } // 将基准元素放到正确的位置上 int temp = nums[low]; nums[low] = nums[right]; nums[right] = temp; return right; // 返回基准元素的位置 } public static void main(String[] args) { QuickSort quickSort = new QuickSort(); int[] nums = {4, 2, 6, 1, 3, 5}; quickSort.quickSort(nums, 0, nums.length - 1); for (int num : nums) { System.out.print(num + " "); } } } ``` 希望以上的建议和示例代码可以帮助你在Java中填实现快速排序算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值