G
Guest
Проблема описана в коде ниже... После выделения функцией malloc памяти под новую переменную значение другой изменяется (в этом примере просто "обрезается", но при нескольких повторениях меняется на совершенно непредсказуемое)
<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++:
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></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;
}