功能结束时的分段错误

时间:2016-01-24 15:03:47

标签: c segmentation-fault

下面你可以找到我的完整代码(是的,我已经改变了它,使其可以用于测试和简短)

它基本上必须读取文件/ var / log / messages并在teste.txt上只写入它找到的IP地址 它运作良好,但它永远不会打印出#8; parte 8 \ n"运行函数后(检查函数main()) 它总是运行良好的代码,打印所有内容,除了功能之后的内容

#include <stdio.h>
#include <string.h>
#include <netinet/ip.h>
#include <arpa/inet.h> // htons e inet_addr
#ifndef __FAVOR_BSD
#   define __FAVOR_BSD
#endif
#include <netinet/udp.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>

#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h> 
#include <stdlib.h>
#include <string.h> 
#include <arpa/inet.h>

#define RANDOM() (int) random() % 255 +1

char * RetornaStringEntreStrings( char * primString, char * segString, char * stringao)
{
    char * posPrim = strstr(stringao, primString);
    if(posPrim <= 0)
    {
        return "";
    }
    posPrim += strlen(primString);

    char * posSeg = strstr(posPrim, segString);

    char * retorno;
    memcpy(retorno, posPrim, posSeg-posPrim);
    retorno[posSeg-posPrim] = 0;
    return retorno;
}

int ExisteIPnoArquivo(char *ip, char *arquivoNome)
{
    FILE *arquivo = fopen(arquivoNome, "r");
    char buffer[128];

    if(arquivo != NULL)
    {
        while(fgets(buffer, 128, arquivo))
        {
            if(strcmp(ip, buffer) == 0)
            {
                fclose(arquivo);
                return 1;
            }
        }
        fclose(arquivo); 
        return 0;
    }
    else
        printf("Nao foi possivel abrir o arquivo.\n");

    return 0;
}

void EscreverArquivo(char * string, char * arquivoNome)
{
    FILE *arquivo = fopen(arquivoNome, "a+");

    if(arquivo == NULL)
    {
        printf("Erro na abertura do arquivo!");
    }
    else
    {
        fprintf(arquivo, "%s", string);
        fclose(arquivo);
    }
}

void SalvarLogsArquivo(char * arquivoNome)
{
    FILE *arquivo = fopen("/var/log/messages", "r");
    char buffer[512];

    // testa se o arquivo foi aberto com sucesso
    if(arquivo != NULL)
    {
        while(fgets(buffer, 512, arquivo))
        {
            char * IP = RetornaStringEntreStrings("SRC=", " ", buffer);
            if(strlen(IP) < 7)
                continue;

            strcat(IP, "\n");
            if(ExisteIPnoArquivo(IP, arquivoNome) == 0)
            {
                printf("Adicionando IP: %s", IP);
                EscreverArquivo(IP, arquivoNome);
            }
            else
                printf("IP ja encontrado: %s", IP);
        }
        fclose(arquivo); // libera o ponteiro para o arquivo
    }
    else
        printf("Nao foi possivel abrir o arquivo.");

    printf("End of Function (segmentation fault below will happen below)\n");
}


int main() 
{
    SalvarLogsArquivo("teste.txt");
    printf("After function, it doesn't run cuz it gets segmentation fault before\n");
}

2 个答案:

答案 0 :(得分:4)

这是原因

char * retorno;
memcpy(retorno, posPrim, posSeg-posPrim);

您没有为retorno分配内存,需要使用malloc()。实施例

retorno = malloc(posSeg - posPrim + 1);
if (retorno != NULL)
{
    memcpy(retorno, posPrim, posSeg - posPrim);
    retorno[posSeg - posPrim] - '\0';
}

答案 1 :(得分:2)

在你的函数RetornaStringEntreStrings()中,你将数据复制到一个未初始化的指针,该指针可能是段错误的(通常是未定义的行为 ):

 char * retorno;
 memcpy(retorno, posPrim, posSeg-posPrim);