繁体   English   中英

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

[英]segmentation fault while assigning string

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(“ \\ n”); agent_address [0] = MasterCPMAddr; ....

我成功地从行agent_address[0] = MasterCPMAddr;获取了字符串agent_address[0] = MasterCPMAddr; 但是在我存储它之后,我遇到了分割错误; //尝试使用strcpy(agent_address[0], MasterCPMAddr)

在c中,参数按值传递。 因此要将agent_address传递给您的函数,您需要像这样声明它:

void getAgentInfo(char*** agent_address )
{

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

注意
您的代码似乎是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 )。
确保分配了存储该字符串所需的内存,并向我们展示如何将变量传递给该字符串。 一个将多个字符串分配给char指针数组的纯C函数可能看起来像这样:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM