Void X(char *a) {...} Нежелательное Изменение Параметра А

Тема в разделе "C/C++/C#", создана пользователем -, 12 ноя 2011.

  1. Гость

    Проблема описана в коде ниже... После выделения функцией malloc памяти под новую переменную значение другой изменяется (в этом примере просто "обрезается", но при нескольких повторениях меняется на совершенно непредсказуемое)
    Код (C++):
    char* new_mem_s(char size)
    {               //выделение памяти под строку
    char* temp=NULL;
    if((temp=malloc(size*sizeof(char)))==NULL)
    {
    printf("Ошибка при распределении памяти\n");
    exit(0);
    }
    return temp;
    }
    form_file(char *(n_ln),pt_elem *(first),pt_elem *(temp),int *(start))
    {
    //здесь n_ln==110111001110101010101 11001010101
    if (*start)
    {
    *temp=new_mem();                     //инициализируем temp                                 
    *first=*temp;                       //сохраняем начало списка
    *start=0;
    }
    //здесь n_ln==110111001110
    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">
    Код программы целиком:</div></div><div class="sp-body"><div class="sp-content">
    Код (C++):
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    typedef struct elem *pt_elem;
    struct elem
    {                               //используемая структура данных
    char *n_ln;                          //строка
    pt_elem next;                         //ссылка на следующий элемент
    };
    FILE *f;                                //файл
    pt_elem new_mem(void)
    {                    //выделение памяти под структуру
    pt_elem temp=NULL;
    if((temp=(pt_elem) malloc(sizeof(struct elem)))==NULL)
    {
    printf("Ошибка при распределении памяти\n");
    exit(0);
    }
    return temp;
    }
    char* new_mem_s(char size)
    {               //выделение памяти под строку
    char* temp=NULL;
    if((temp=malloc(size*sizeof(char)))==NULL)
    {
    printf("Ошибка при распределении памяти\n");
    exit(0);
    }
    return temp;
    }
    form_file(char *(n_ln),pt_elem *(first),pt_elem *(temp),int *(start))
    {
    printf("%s","form_file  ");printf("%s",n_ln);printf("%c",'\n');
    if (*start)
    {
    *temp=new_mem();                     //инициализируем temp                                 
    *first=*temp;                       //сохраняем начало списка
    *start=0;
    }
    printf("%s","form_file  ");printf("%s",n_ln);printf("%c",'\n');
    (*temp)->n_ln=new_mem_s(strlen(n_ln)+1); //выделяем память под строку
    strcpy((*temp)->n_ln,n_ln);          //копируем в выделенную память
    (*temp)->n_ln[strlen(n_ln)]='\0';       //записываем после '\n' '\0'
    (*temp)->next=new_mem();                 //память под след. элемент
    (*temp)=(*temp)->next;                //и устанавливаем его текущим
    }
    void write_file (char *(n_ln),pt_elem *(first),pt_elem *(temp),int *start)
    {  
    if (*start)
    {                                
    *temp=*first;                       //загружаемем начало списка
    *start=0;                           //сбрасываем флагя
    }
    int error=fputs((*temp)->n_ln,f);       //вывод в файл строки
    if (error==EOF)
    {
    printf("Ошибка при записи результата\n");
    exit(0);
    }
    pt_elem disp;                           //временная переменная для очистки
    disp=*temp;
    (*temp)=(*temp)->next;                //переход к следующему элементу
    //free(disp->n_ln);                     //освобожение данных элемента и
    //free(disp);                            //самого элемента
    }
    char* inverse(char* ln)
    {                 //инверсия символов строки
    int length=strlen(ln);
    char i;
    char* tmp_i=NULL;
    tmp_i=new_mem_s(length);          //инициализируем промежут. строку
    for (i=0;i<length-1;i++)
    {            
    tmp_i[i]=ln[length-2-i];             //инвертируем
    }
    for (i=0;i<length-1;i++)
    {            
    ln[i]=tmp_i[i];                  //результат инверсии в ln         
    }
    //free(tmp_i);                           //освобождаем память
    return ln;
    }
    char* hex_str (char *ln)
    {
    char dex;                             //десятичное значение тетрады
    char* rez=new_mem_s(1);              //hex значение числа
    rez[0]='\0';
    char i;                              //счетчик цикла
    char* tetr=new_mem_s(5);                //тетрада из числа
    while (strlen(ln))
    {                 //пока обработано не все число
    for(i=0;i<4;i++)
    {                //выделяем тетраду
    if (ln[3-i]!='\0')           //если в ней 4 бита, то
    tetr[i]=ln[3-i];            //обрабатываем простым способом
    else
    {                        //если меньше, то
    while(strlen(ln)!=4)
    {
    ln[strlen(ln)+1]='\0';
    ln[strlen(ln)]=48;
    }
    ln[strlen(ln)+1]='\0';
    ln[strlen(ln)]='\n';
    ln=inverse(ln);
    for(i=0;i<4;i++)
    tetr[i]=ln[i];
    ln[0]='\0';
    break;
    }
    }
    dex=(tetr[0]-48)*8+(tetr[1]-48)*4+(tetr[2]-48)*2+tetr[3]-48;
    tetr[0]='\0';                 //очищаем tetr
    if (strlen(ln)!=0)
    ln=ln+4;                    //"удаляем" обработанные символы
    rez=realloc(rez,strlen(rez)+1);
    if (dex<10)
    dex=dex+48;
    else
    dex=dex+55;
    rez[strlen(rez)]=dex;
    }
    rez=realloc(rez,strlen(rez)+1);
    rez[strlen(rez)]='\n';
    rez=inverse(rez);
    rez[strlen(rez)-1]='\0';
    return rez;
    }
    char* str_chisl (char *ln)
    {
    char i;
    char* chisl;
    char* rez;
    char* line=new_mem_s(1);
    line[0]='\0';
    char point=0;                        //смещение в строке результата
    while (ln[0]!='\0')
    {
    char* tmp_p=strchr(ln,32);
    if (tmp_p==NULL)
    {
    point=point+strlen(ln);
    chisl=new_mem_s(strlen(ln));
    for (i=0;i<strlen(ln)+1;i++)
    {
    chisl[i]=ln[i];
    }
    chisl[i-2]='\0';
    ln[0]='\0';
    }
    else
    {
    i=0;
    point=point+(tmp_p-ln);
    chisl=new_mem_s(tmp_p-ln);
    while(tmp_p!=ln)
    {
    chisl[i]=ln[0];
    ln=ln+1;
    i++;
    }
    ln=ln+1;
    }
    int pos_tmp=strlen(chisl);
    chisl[pos_tmp]='\n';
    chisl[pos_tmp+1]='\0';
    chisl=inverse(chisl);
    chisl[pos_tmp]='\0';
    rez=hex_str(chisl);
    char* probel=new_mem_s(255);
    memset(probel,32,point-1);
    probel[point]='\0';
    strcat(probel,rez);
    line=new_mem_s(255);// line=realloc(line,(strlen(probel)+strlen(line))*8);
    strcat(line,probel);
    }
    return rez;
    }
    int main()
    {  
    char* ln="Start";                               //строка символов
    pt_elem first;                       
    pt_elem temp;
    long long int j=0;                        //количество элементов списка
    long long int i;                         //счетчик
    int start=1;                             //первый запуск функции
    if ((f=fopen("f","r"))==NULL)
    {         //открываем для записи
    printf("Невозможно открыть файл\n");
    exit(0);                             
    }
    printf("%s","Файл открыт для записи\n");
    while (strlen(ln)!=0)
    {                     //пока не конец файла
    int length=257;
    ln=new_mem_s(length);
    fgets(ln,length,f);
    if (strlen(ln)==0)
    break;
    printf("%s","Вход в form_file с  ");printf("%s",ln);printf("%c",'\n');
    form_file(&*ln,&first,&temp,&start);     //запись строки в список
    printf("%s","Выход из form_file с ");printf("%s",ln);printf("%c",'\n');
    ln=str_chisl(ln);
    form_file(&*ln,&first,&temp,&start);     //запись строки-результата
    j=j+2;
    }
    if ((f=fopen("f","a"))==NULL)
    {         //открываем для записи
    printf("Невозможно открыть/создать файл\n");
    exit(0);                             
    }
    start=1;
    for (i=0;i<j;i++)
    {
    write_file (&*ln,&first,&temp,&start);
    }
    return 0;
    }
     
  2. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    У тебя все время выделяется до 256 байт функцией new_mem_s ?
     
  3. Гость

    Нет, где-то меньше. Кстати, значение n_ln в form_file обрезается после выполнения new_mem(), т.е. malloc(sizeof(struct elem))
     
  4. lazybiz

    lazybiz Well-Known Member
    C\C++ Team

    Регистрация:
    3 ноя 2010
    Сообщения:
    1.344
    Симпатии:
    0
    Похоже мы на разных языках с тобой разговариваем.

    Код (C++):
            int length=257;
    ln=new_mem_s(length);
    Думаю ничего объяснять не надо.

    Смотри протопит функции new_mem_s.
     
  5. Гость

    Гм...когда программу только начинал писать, тип был int. Потом поменял и напрочь забыл. Спасибо большое за столь быструю помощь.
     

Поделиться этой страницей