分配字符串时出现分段错误

时间:2014-07-07 10:20:55

标签: c++ c

void getAgentInfo( char** agent_address )
{
    #define MAX_IP_SIZE 100
    FILE *fcfg=NULL;
    char line[MAXLINE];
    char *p , *pend;
    int findlen_ips, findlen_num;
    findlen_ips = strlen (findkey_ips);
    findlen_num = strlen (findkey_num);
    int iCount = 1; //in agent array entry
    fcfg = fopen (FCFG, "r");

    while (p = fgets (line, MAXLINE, fcfg))
    {
        //printf ("Looking at %s\n", p);
        if (p = findval (line, findkey_num, findlen_num))
        {
            pend = p + strlen (p) - 1;  /* check last char for newline terminator */
            if (*pend == '\n')
                *pend = 0;
            printf ("%s\n", p); /* process/parse the value */
            NumOfIp = atoi(p);
            //agent_address = (char*)calloc(NumOfIp + 1, sizeof(char));
            agent_address = new char*[NumOfIp + 1];
            for(int icount = 0; icount < NumOfIp+1; icount++)
            {
                agent_address[icount] = new char[MAX_IP_SIZE];
            }
        }

        if (p = findval (line, findkey_ips, findlen_ips))
        {
            pend = p + strlen (p) - 1;  /* check last char for newline terminator */
            if (*pend == '\n')
                *pend = 0;
            printf ("addr = %s\n", p); /* process/parse the value */
            agent_address[iCount]= p; //strcpy(agent_address[iCount], p)
            //printf("agent_address[iCount++]=%s\n",agent_address[iCount]);
            iCount++;
        }
    }
}

从上面的代码中我读取了一个txt文件,并在int var中获取值,并根据该值将2d字符串数组用于存储值:

...         char ** agent_address = NULL;         getAgentInfo(agent_address);         TRACE_STR(&#34; \ n&#34);         agent_address [0] = MasterCPMAddr; ....

我成功地从第agent_address[0] = MasterCPMAddr;行获取字符串,但是当我存储它时,我得到了分段错误; //尝试使用strcpy(agent_address[0], MasterCPMAddr)

2 个答案:

答案 0 :(得分:1)

在c中,参数按值传递。所以要将agent_address传递给你的函数,你需要声明它如下:

void getAgentInfo(char*** agent_address )
{

然后在函数内取消引用agent_address 目前,函数中的agent_address只是一个局部变量。

答案 1 :(得分:1)

注释
你的代码似乎是C,带有轻量级的C ++。我建议你选择一个方面。用C或C ++编写。后者提供了一个强大的库,可以为您处理文件IO和内存管理的细节。将std::vector<std::string>传递给您的函数在这里是有意义的。解决问题的更多C ++风格是:

int read_lines(std::vector<std::string>& lines)
{
    int count_lines = 0;
    std::string line;
    std::ifstream infile("file.txt");
    while (std::getline(infile, line))
    {
        lines.push_back(line);//add line to vector
        ++count_lines;
    }
    return count_lines;
}

完整,经过测试和运作的例子:

#include <iostream> 
#include <fstream>
#include <vector>

using namespace std;//to get rid of that pesky std::

int read_lines(vector<string>& lines)
{
    int count_lines = 0;
    string line;
    ifstream infile("file.txt");
    while (getline(infile, line))
    {
        lines.push_back(line);//add line to vector
        ++count_lines;
    }
    return count_lines;
}

int main ( void )
{
    vector<string> list;
    int lines_read = read_lines(list);
    int i=1;
    cout << "Read " << lines_read << " lines" << endl;
    //from start to finish
    for (vector<string>::iterator it = list.begin(); it != list.end(); ++it)
        cout << "Line: " << i++ << " "<< *it << endl;
    return 0;
}

如果你想用老式的C-way做这个,那么这就是我对你问题的回答:

您有未定义的行为。在getAgentInfo函数内部,您有一个指向字符串(ppend)的指针。但是,这些指针仅在函数内有效。您必须将实际字符串复制到agent_address变量(使用strcpystrncpy)。
确保分配存储该字符串所需的内存,并向我们展示如何将变量传递给。一个纯C函数将一些字符串分配给一个char指针数组,看起来像这样:

int read_lines(char *store_lines[], size_t max_lines)
{
    int i=0;
    size_t len;
    char buffer[200];//temp buffer
    FILE *fp = fopen("file.txt", "r");
    if (fp == NULL)|
        return -1;//error
    while (i < max_lines && fgets(buffer, sizeof buffer, fp) != NULL)
    {//read lines while we haven't reached the max, and there are lines to read
        len = strlen(buffer);
        store_lines[i] = malloc(len+1);//allocate memory
        if (store_lines[i] == NULL)
        {
            fclose(fp);//ALWAYS fclose
            return 0;//failed to allocate enough memory
        }
        *store_lines[i] = '\0';//set to empty
        strncat(store_lines[i], buffer, len);
        ++i;//next line
    }
    fclose(fp);
    return i;//return number of lines read
}

您可以使用如下指针数组调用此函数:

char *data[10];
int check = read_lines(data, 10);
if (check == -1)
{
    fprintf(stderr, "unable to open file");
    exit(1);
}
if (check == 0)
{
    fprintf(stderr, "failed to allocate memory\n");
    for (int i=0;data[i] != NULL;++i)
        fprintf(stderr, "Read line %d: %s\n", i+1, data[i]);//allocated memory vs null-pointers, possible to free memory here
    exit(1);
}
printf("Read %d lines out of %d\n", check, sizeof data/sizeof *data);
for (int i=0;i<check;++i)
{
    printf("Line %d: %s\n", i+1, data[i]);
    free(data[i]);
    data[i] = NULL;
}
return 0;

如果您希望read_lines函数也分配数组本身,则必须将指针的地址传递给指针(三个间接级别)。但是为了你自己和那些你爱的人,尽可能避免:

int read_lines(char ***store_lines)
{
    char buffer[200],
        **target = *store_lines;//makes it easier
    size_t len, i;
    FILE *fp = fopen("file.txt", "r");
    if (fp == NULL)
        return -1;
    while(fgets(buffer, sizeof buffer, fp))
    {
        len = strlen(buffer);
        realloc(target, (1+i)*sizeof *target);//re-allocate memory for pointer array
        if (target == NULL)
        {
            fclose(fp);
            return 0;
        }
        target[i] = malloc(len+1);//allocate space for chars
        if (target[i] == NULL)
        {
            fclose(fp);
            return 0;
        }
        *target[i] = '\0';//empty string, enable strncat use
        strncat(target[i], buffer, len);
        ++i;//next line
    }
    fclose(fp);
    return (int) i;//cast to int - optional
}

您可以像这样调用此函数:

char **data = NULL;
int lines_read = read_lines(&data);
if (lines_read == -1)
{
    fprintf(stderr, "Could not open file");
    exit (EXIT_FAILURE);
}
if (lines_read == 0)
{
    fprintf(stderr, "Not enough RAM");
    exit (EXIT_FAILURE);
}
for (int i=0;i<lines_read;++i)
    printf("%d) %s\n", i, data[i]);//print out line-by-line
//free memory