You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C语言execvp传递程序参数失败,参数无法正确转发

问题根源分析与解决方案

这问题我一眼就戳中要害了——你犯了C语言指针使用的经典错误:所有array1的元素都指向同一个内存块buf1!

为什么会出现3 3 3的结果?

看你这段核心代码:

char buf1[50];
char *array1[4];
for (int i = 0; i < 3; i++){
    bytes_recieved1 = recv(clientfd, buf1, 50, 0);
    array1[i] = buf1; // 关键错误在这里!
    printf("%s = buffer\n", buf1);
}

每次循环里,recv都会把新参数写入buf1这个固定的栈内存,而你只是把buf1的起始地址赋值给array1[i]。循环结束后,buf1里存的是最后一次接收的内容"3",array1[0]、array1[1]、array1[2]三个指针全指向同一块内存,自然传递给目标程序后,所有参数都显示成最后一个值。

而你手动赋值array1[0] = "1";时,每个字符串字面量都存在独立的只读内存区域,指针指向不同地址,所以能正常工作。

修正方案

你需要为每个参数分配独立的内存空间,把buf1的内容复制进去,而不是直接复用同一个缓冲区的地址。同时还要注意execvp的要求:参数数组必须以NULL结尾。

这里给你修改后的代码,顺便修复了其他潜在问题:

// 先修正buf的大小,避免recv时缓冲区溢出
char buf[5000];
int bytes_recieved = recv(clientfd, buf, sizeof(buf)-1, 0);
if (bytes_recieved == -1) {
    perror("recv program name failed");
    return 1;
}
buf[bytes_recieved] = '\0';

char buf1[50];
char *array1[4];
for (int i = 0; i < 3; i++){
    int bytes_recieved1 = recv(clientfd, buf1, sizeof(buf1)-1, 0);
    if (bytes_recieved1 == -1) {
        perror("recv argument failed");
        // 错误时要释放已分配的内存,避免泄漏
        for (int j = 0; j < i; j++) {
            free(array1[j]);
        }
        return 1;
    }
    buf1[bytes_recieved1] = '\0'; // 正确设置字符串终止符
    
    // 为当前参数分配独立内存并复制内容
    array1[i] = malloc(strlen(buf1) + 1);
    if (array1[i] == NULL) {
        perror("malloc failed");
        for (int j = 0; j < i; j++) {
            free(array1[j]);
        }
        return 1;
    }
    strcpy(array1[i], buf1);
    printf("%s = buffer\n", array1[i]);
}
array1[3] = NULL; // execvp要求参数数组必须以NULL结尾

printTime();
fprintf(stdout,"attempting to execute program: %s\n", buf);
if(execvp(buf, array1) == -1) {
    perror("execvp failed");
    // 释放内存后再返回错误
    for (int i = 0; i < 3; i++) {
        free(array1[i]);
    }
    return 1;
}

额外注意事项

  1. 错误处理:一定要检查recv、malloc的返回值,避免程序崩溃或内存泄漏;
  2. 粘包问题:如果客户端和服务端没有明确的参数分隔协议(比如每个参数固定长度、先传参数个数),recv可能会出现多个参数粘在一起的情况,需要补充协议逻辑;
  3. 缓冲区大小:如果参数长度可能超过50,要调整buf1的大小,或者改成动态分配内存接收参数。

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:12:44