Запись Pipe перезаписывает выделенное пространство памяти

Моя программа довольно большая, поэтому я выделю основную проблему и добавлю некоторые подробности о ней.

Первая часть моего кода:

int myPipe[2]; //A global variable, so I don't have to pass it to future functions

int main(int argc, char *args[]) 
{
    mode_t pUmask = umask(0000); //Obsolete variable to my problem
    errno = 0; //Obsolete variable to my problem
    char pattern[2500] = "Test1"; //Obsolete variable to my problem
    int p = 0;              //DEFAULT NUMBER OF PROCESSES
    int deep = 0; //Obsolete variable to my problem
    int n = 1; //Obsolete variable to my problem

    if(pipe(myPipe))
    {
        perror("Pipe Error: ");
        exit(-1);
    }
    
    if( (write(myPipe[1], &p, (sizeof(int)*3))) == -1) //First write works
    {
        perror("write: ");
        exit(-1);
    }
    //Then a bunch of code releated to file reading
}

Вторая часть:

{
    //in another function
    //The part where I create fileName
    char* fileName = calloc(strlen(fileData->d_name)+4, sizeof(char));
    strcpy(fileName, fileData->d_name);
}

Третья часть:

//in another another function
if(S_ISREG(data.st_mode))
{
    printf("\tfileName: %s\n", fileName); //Regular print of the right fileName
    printf("\t\tOh boy! It's a regular.\n");
    printf("\tfileName: %s\n", fileName); //Regular print of the right fileName

    if((read(myPipe[0], &p, (sizeof(int)*3))) == -1) //First time I read
    {
        perror("\t\t read: ");
        exit(-1);
    } 
    printf("fileName: %s", fileName); //SEGMENTATION FAULT

Между ними есть куча кода, но он вообще не влияет на имя файла (на самом деле, до чтения имя файла печаталось безупречно), а после этого происходит ОШИБКА СЕГМЕНТАЦИИ.

В какой-то момент, изменив расположение printfs, я смог получить имя файла ПОСЛЕ чтения, которое в основном представляло собой значение имени файла (Файл1), за которым следовало целочисленное значение p (0), которое создало новое поврежденное имя файла (Файл10).

Так что же происходит? Я зарезервировал место для имени файла, я передал указатель имени файла следующим функциям до этого чтения, и, предположительно, у fd также должно быть собственное адресное пространство. ПОМОЩЬ.

P.S. если вам нужна дополнительная информация, я готов предоставить ее вам, даже полный код, но это ДЕЙСТВИТЕЛЬНО сложно, и я думаю, что предоставил вам достаточно доказательств того, что имя файла вообще не повреждается до прочитанной части, СПАСИБО .

P.P.S. Я никогда не закрываю ни одну из крайностей MyPipe, так как мне приходится использовать их несколько раз, я хотел закрыть их в конце программы.


person B.Castarunza    schedule 15.05.2020    source источник
comment
p это всего лишь один int, зачем ты пишешь и читаешь sizeof(int)*3?   -  person Barmar    schedule 15.05.2020
comment
Это вызывает неопределенное поведение, поскольку вы обращаетесь за пределами объекта.   -  person Barmar    schedule 15.05.2020
comment
@Barmar Потому что в будущем p может содержать до 3 цифр (на самом деле p устанавливается пользователем с основными аргументами, и есть вероятность, что он может вставить 100)   -  person B.Castarunza    schedule 15.05.2020
comment
@ B.Castarunza Какое отношение цифры имеют к чему-либо? Мы говорим о значениях, которые не содержат цифр. (Цифры являются атрибутом конкретных представлений значений.)   -  person David Schwartz    schedule 15.05.2020
comment
@B.Castarunza Поскольку p является int, длина p равна sizeof(int).   -  person David Schwartz    schedule 16.05.2020
comment
О, теперь я начинаю понимать. Ok.   -  person B.Castarunza    schedule 16.05.2020
comment
Цифры находятся в строках символов, а не в целых числах. Вы должны использовать sprintf() для преобразования int в цифры.   -  person Barmar    schedule 16.05.2020


Ответы (1)


Операторы, которые записывают и читают канал, вызывают неопределенное поведение. p объявляется:

int p;

Но когда вы пишете и читаете его через канал, вы используете sizeof(int)*3, поэтому вы обращаетесь за пределами объекта.

Измените эти операторы, чтобы использовать только sizeof p.

person Barmar    schedule 15.05.2020