【问题标题】:Segmentation fault (core dumped) from command line argument来自命令行参数的分段错误(核心转储)
【发布时间】:2016-11-17 19:43:07
【问题描述】:

我正在尝试使用参数从终端运行一些代码。这是我的代码:

int PORT_NUM = 0;
int BYTES_TO_SEND = 0;
char* LocalAddresss = "";


char* concat(char *s1, char *s2)
{
    char *result = malloc(strlen(s1)+strlen(s2)+1);
    strcpy(result, s1);
    strcat(result, s2);
    return result;
}

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    char data[BYTES_TO_SEND];

    LocalAddresss = concat("192.168.1.",argv[1]);
    PORT_NUM = atoi(argv[2]);
    BYTES_TO_SEND = atoi(argv[3]);

    fflush(stdout);

    for(int i = 0; i < BYTES_TO_SEND; i++){
        data[i] = 'Z';
    }

    char* message_to_send = data;

    portno = PORT_NUM;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");

    server = gethostbyname(LocalAddresss);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);

    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");

    while(1){
        n = write(sockfd,message_to_send,strlen(message_to_send));
    }

    close(sockfd);
    return 0;
}

我的问题是这个。以下工作:./TCP_client 16 2000 100 在命令行上。

这不是:./TCP_client 16 2000 3000

我收到“分段错误(核心转储)”

命令行参数的总字节数有限制吗?我该如何解决这个问题?

使用 GDB 运行它后,它显示“程序收到信号 SIGBUS,总线错误。0x0000000100000ccf in main ()”虽然不太确定这是什么。

【问题讨论】:

  • c 对命令行参数大小没有限制。这是你的外壳强加的。你需要展示这个concat 函数在做什么。这不是标准的 C 函数。字符串连接由strcat 完成。而且由于您失败的一个字符比另一个长一个字符,因此您可能在某个地方发生了溢出。
  • 你是在调试器下运行的吗?它会告诉你崩溃的地方
  • @VishnuMurale 这是完整代码吗?你包括哪些标题?
  • 使用 -g 编译代码,然后在 GDB 下运行,请修复我在回答中显示的 v 严重错误

标签: c segmentation-fault command-line-arguments


【解决方案1】:

如果我是你,我会使用 string.h 库中的 strcat() 函数。

#include <string.h>
...
char LocalAddresss[15] = "192.168.1.";
strcat(LocalAddress, argv[1]);

【讨论】:

  • 数组不够是什么意思??
  • 数组大小不够。初始化的值已经在使用11
  • 现在明确写入数组之外(仅在注释中),但比安全更危险。
【解决方案2】:

这会失败,因为您声明的数据大小为 0

int BYTES_TO_SEND = 0;
...
char data[BYTES_TO_SEND];
'''
LocalAddresss = concat("192.168.1.",argv[1]);
PORT_NUM = atoi(argv[2]);
BYTES_TO_SEND = atoi(argv[3]);

你需要移动线条

int BYTES_TO_SEND = 0;
...
LocalAddresss = concat("192.168.1.",argv[1]);
PORT_NUM = atoi(argv[2]);
BYTES_TO_SEND = atoi(argv[3]);
char data[BYTES_TO_SEND];
'''

但这是一个糟糕的计划 - 将一个像这样的大缓冲区放在堆栈上,最好对其进行 malloc。您的示例将起作用,但它不是一个好的设计

【讨论】:

  • 这并不能解决我的问题。此外,“./TCP_client 16 2000 100”有效而“./TCP_client 16 2000 3000”无效,这一事实让我认为问题出在其他地方。
  • 你得到了未定义的行为,事情会随机工作并随机失败。您的代码中可能有其他错误,但这肯定是一个严重的错误。你是在调试器下运行的吗?
  • 我的立场是正确的。我想我一定忘了用你的编辑重新编译,但这似乎解决了它。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 2021-06-03
相关资源
最近更新 更多