C++ 分析变量和分段错误(核心转储)错误

C++ 分析变量和分段错误(核心转储)错误,c++,segmentation-fault,C++,Segmentation Fault,为了将每个单独的单词存储在它自己的变量中,我在将用户字符串作为变量传入时遇到了一个问题。下面是我的尝试 client.c中还有一部分程序正在请求用户输入。在客户端“foo 123 anwhere blah”中键入字符串后,它将作为变量buf传递到下面的服务器程序中。一旦我有了它,我就把它复制到temp,这样我就不会损坏原始字符串(至少在测试的这个时候)。然后,我对试图解析每个单词的变量运行strctok 如果我在正确的轨道上的时刻,它将编译没有错误和运行。但是,当我从客户端向它发送数据时,会出现

为了将每个单独的单词存储在它自己的变量中,我在将用户字符串作为变量传入时遇到了一个问题。下面是我的尝试

client.c
中还有一部分程序正在请求用户输入。在客户端“foo 123 anwhere blah”中键入字符串后,它将作为变量
buf
传递到下面的服务器程序中。一旦我有了它,我就把它复制到
temp
,这样我就不会损坏原始字符串(至少在测试的这个时候)。然后,我对试图解析每个单词的变量运行
strctok

如果我在正确的轨道上的时刻,它将编译没有错误和运行。但是,当我从客户端向它发送数据时,会出现“分段错误(堆芯转储)”

有人能解释一下原因吗

        /*
 * server.c
*/

#include <stdio.h>
#include <iostream>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> 
#include <netdb.h>
#include <cstring>
#include <cstdlib>

using namespace std;

#define SERVER_PORT 1617 
#define MAX_PENDING 5
#define MAX_LINE 256

int main(int argc, char **argv) {

struct sockaddr_in sin;
socklen_t addrlen;
char buf[MAX_LINE];
int len;
int s;
int new_s;
char *temp;
char fname[32], lname[32], city[32], zip[32], country[32];

/* build address data structure */
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons (SERVER_PORT);

/* setup passive open */
if (( s = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("socket");
    exit(1);
}

if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
    perror("bind");
    exit(1);
}

listen (s, MAX_PENDING);

addrlen = sizeof(sin);
cout << "The server is up, waiting for connection" << endl;

/* wait for connection, then receive and print text */
while (1) {
    if ((new_s = accept(s, (struct sockaddr *)&sin, &addrlen)) < 0) {
        perror("accept");
        exit(1);
    }
    cout << "new connection from " << inet_ntoa(sin.sin_addr) << endl;

    while (len = recv(new_s, buf, sizeof(buf), 0)) {

        temp = buf;
        strcpy(fname, strtok(buf , " "));
            strcpy(lname, strtok(NULL, " "));
            strcpy(city , strtok(NULL, " "));
            strcpy(zip , strtok(NULL, " "));
            strcpy(country, strtok(NULL, " "));


            printf("%s\n", fname);
            printf("%s\n", lname);
            printf("%s\n", city);
            printf("%s\n", zip);
            printf("%s\n", country);


        /* send (new_s, temp, strlen(temp) + 1, 0); */
    }

    close(new_s);
}
}                      

用strncpy替换strcpy。并根据要复制的缓冲区长度在strncpy中使用正确的长度。
另外,您没有检查strtok的返回值。由于strtok可以返回NULL,因此您正在尝试执行strcpy(str,NULL)之类的操作。

这里有几个潜在问题。首先,

temp=buf
不将buf复制到temp,它只是复制指针。在这行之后,
temp
只指向与
buf
相同的位置。您需要为temp分配内存,并执行
memcpy
或类似操作

其次,需要检查
len
的值。不能保证
recv
收到的数据与您预期的一样多。这意味着您可能需要执行多个
recv
调用才能获得完整的字符串


如果您可以发布核心文件的堆栈跟踪,这将对其他审阅者有所帮助。至少这将指向冒犯的行。< /p>删除C++标签。你从字符串中解析5个单词,但是你的示例输入只有4个。为什么你在其他C程序中包含<代码> IOStry?因为我不确定程序是什么语言,我使用了一些C和一些C++,或者我被告知我可以用C++来操纵字符串,然后把它们返回到C代码>我可以用C++来操纵字符串,然后把它们返回到c<代码> >我建议你这样做!尼尔·柯克:如果您能提供这方面的任何建议,我将不胜感激。我整个星期都在做这方面的工作,今天也一直在做,但我没有取得任何进展:(我不确定“核心文件堆栈跟踪”是什么……或者如何获取它们,或者我非常乐意发布它们:)我换了一个新的memcpy@ff210327您可以通过使用gdb之类的调试器打开核心文件来获得堆栈跟踪。堆栈跟踪将显示导致分段错误的行的完整调用堆栈。确保使用调试信息进行编译,以使其工作(-gcc中的g标志)。我建议阅读调试程序,因为它们将是您的朋友。@ff210327对不起,我应该更清楚一些。gcc-g向创建的可执行文件添加额外信息。然后,调试器可以在调试正在运行的进程或核心文件时使用此信息为您提供更好的信息。您发布的是编译器在解析代码时检测到的一系列警告。修复这些警告是一种很好的做法,因为它们通常会指向代码中更大的问题。