realloc w funkcji, oszaleje :/

0

Witam
Pogubiłem się totalnie. Proszę o podpowiedź bo nie wiem gdzie leży błąd w toku rozumowania wskaźników.
Problem z linią: symbols_arr[cnt_tmp] = &symbol;

#include <stdio.h>
#include <stdlib.h>


int read_from_file(FILE *pliczek, char ***symbols_arr)
{
        // BUFSIZ zdefiniowany w std
	 char buffLine[BUFSIZ];
	 int cnt = 0;
	 int cnt_tmp = 0;

        // Czytamy lini po lini
	 while(fgets(buffLine, sizeof(buffLine), pliczek) != NULL)
     {
		 // Alokujemy pamiec dla symbolu
		 char *symbol = (char*)malloc(strlen(buffLine) * sizeof(char));

                 // Kopiujemy do symbolu 
		 memcpy(symbol, buffLine, strlen(buffLine));
                 
                 // Usuwamy znak nowej linii i konczymy go nullem
		 symbol[strlen(buffLine)-1] = '\0';
		 
		 if(!symbol)
		 {
			 free(symbol);
			 perror("Error while allocating memory for symbol\n");
			 exit(1);
		 }
		 

		 // Tworzymy miejsce w pamieci na nowa tablice
	         char **symbols_tmp = (char**)realloc(*symbols_arr, ++cnt * sizeof(char*));
		 if(!symbols_tmp)
		 {
			 free(symbols_arr);
			 perror("Error while allocating memory for symbols\n");
			 exit(1);
		}
              // Tutaj działa - teraz  symbol_arr wskazuje na adres pamięci nowo powstałej tablicy
	      symbols_arr = &symbols_tmp;


             // Tu się sypie kompilator - chce przypisac adres char`a *symbol do "świeżej" tablicy pod indeksem cnt_tmp...
             // tak zeby moc miec do niej dostep w main() np: printf("%s\n", symbols[indeks]);
		 symbols_arr[cnt_tmp] = &symbol;
		 cnt_tmp++;
	 }

	 return cnt;
}


int main()
{
  
  char **symbols = NULL;
  
  FILE *symbols_file = fopen("D:\\kupa.txt", "r");

  int symbols_cnt = read_from_file(symbols_file, &symbols);

  fclose(symbols_file);


  free(symbols);
  printf("Done: %d\n", symbols_cnt);
  getchar();
  return 0;
}
0
*symbols_arr=symbols_tmp;
0

Fakt, tylko nadal to działa przy pierwszej iteracji. Jak przechodzę na drugą linie w pliku w while() to mam znowu ten sam błąd IsValidHeapPointer(pUserData):(char**)realloc(symbols_arr, cnt * sizeof(char)); w VS Express :(

dzięki.

0

char *symbol=strdup(buffLine);
przy tym symbole za mało pamięci przydzielasz.

0

Wygląda na to że dobrze przydzielam :| Używając strdup() też się wysypuje przy realloc() - już testowałem.

0
(*symbols_arr)[cnt_tmp]=symbol;

lub:

symbols_tmp[cnt_tmp]=symbol;
0

Długo bym na to nie wpadł. Masakra.

int read_from_file(FILE *pliczek, char ***symbols_arr)
{
	 char buffLine[BUFSIZ];
	 int cnt = 1;
	 int cnt_tmp = 0;

	 while(fgets(buffLine, sizeof(buffLine), pliczek) != NULL)
     {
		 // Allocate memory for one symbol from file
		 char *symbol = (char*)malloc(strlen(buffLine) * sizeof(char));

		 if(symbol == NULL)
		 {
			 free(symbol);
			 perror("Error while allocating memory for symbol\n");
			 exit(1);
		 }

		 memcpy(symbol, buffLine, strlen(buffLine));
		 symbol[strlen(buffLine)-1] = '\0';
	

		 // Add symbol to dynamic array
	     char **symbols_tmp = (char**)realloc(*symbols_arr, cnt * sizeof(char*));
		 if(!symbols_tmp)
		 {
			 free(symbols_arr);
			 perror("Error while allocating memory for symbol list\n");
			 exit(1);
		 }
	      *symbols_arr = symbols_tmp;
		
		 (*symbols_arr)[cnt_tmp] = symbol;
		 cnt_tmp++;
		 cnt++;
	
		
	 }

	 return cnt;
}

 

w main():

for(i =0; i < 3; i++)
  {
	  printf("%s\n", symbols[i]);
  }
 

Dzięki za pomoc.

0

tak, tak :-). jeszcze tylko myślę jak ominąć problem obcinania ostatniego z znaku w ostatniej linijce tj symbolu. Jak plik ma ostatni EOF znak = '\n' to spokojnie działa natomiast jak ma

gie
bla
opk

tu utnie 'k'. Jakoś to ogarnę. Z tymi wskaźnikami się już męczyłem którąś godzinę.

Jeszcze raz dzięki za pomoc.

0
char *symbol=strchr(buffLine,'\n');
if(symbol) *symbol=0;
symbol=strdup(buffLine);
0

Cześć. Napisałem już praktycznie część mojego kodu i znowu mam problem z realloc tym razem w callback'u size_t write_to_memory linia z realloc.
Wygląda to tak:

 

typedef struct MemoryStruct 
{
	char *memory;
	size_t size;
};

// Callback
// userp = adres ustawiony w WRITEDATA
// contents = pobrane dane
static size_t write_to_memory(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
 
   struct MemoryStruct *mem = (struct MemoryStruct *)userp;

   // Tu printuje - działa
   printf("%s %d\n", mem->memory,  mem->size);
 
  //
  //
  // Tutaj jest problem - system wypluwa "Access Volation" - nie potrafi dobrać się do mem->memory
  // char *mem_tmp = (char*)realloc(mem->memory, mem->size + realsize + 1);
  //
 //
// To  musimy zwrócić !
  return realsize; 
}

// curl_handlers - przechowuje gotowe handlery dla curl_multi 
// curl_results - tutaj pobrane dane
// url_list - tablica zawierjące url`e
// url_list_size - rozmiar powyższej tablicy

int prepare_curl_handles(CURL ***curl_handlers, MemoryStruct ***curl_results, char **url_list, int url_list_size)
{
	int i = 0, cnt = 0;
	for(i = 0; i < url_list_size; i++)
	{
       // Inicjalizuje nowy handler CURL`a
	   CURL *http_handle;
       http_handle = curl_easy_init();

	   cnt++;

	   // Zwiekszam dynamiczna tablice curl_results
	   MemoryStruct **curl_results_tmp = (struct MemoryStruct**)realloc(*curl_results, cnt * sizeof(struct MemoryStruct*));
	   *curl_results = curl_results_tmp;
	   
	   // Tworze nowa strukture mem
	    struct MemoryStruct *mem = (struct MemoryStruct*)malloc(sizeof(struct MemoryStruct));

	   // Domyślne wartości
           mem->memory = (char*)malloc(1);	   
	   mem->size =0;
	 
	   // Zapisuje wskaznik nowo powstalej struktury do tablicy
	   (*curl_results)[cnt-1] = mem;

	   printf("mem addres: %p, curl_results[] addres %p\n", mem, (*curl_results)[cnt-1]);
	  
          // Przypisuje url
	   curl_easy_setopt(http_handle, CURLOPT_URL, url_list[i]);
           
           //
	   // Wysyłam adres powstałej struktury - adres będzie dostępny jako ostatni argument w funkcji write_data - void *userp
	   curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, (void*)&mem);
           //
	   // Ustawiam callbacka
	   curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, write_to_memory);
	   //
	   // Zwikeszam dynamiczna tablice zawierająca handlery dla CURL MULTI
	   CURL **curl_handlers_tmp = (CURL**)realloc(*curl_handlers, cnt * sizeof(CURL*));
	   *curl_handlers = curl_handlers_tmp;

	   (*curl_handlers)[cnt-1] = http_handle;

	}
	return cnt-1;
}

W programie ogólnie chodzi o to żeby CURL MULTI wysyłał pobierane dane do dynamicznej tablicy MemoryStruct ***curl_results pod danym indeksem. Przykładowo jeśli pobiera url o indeksie 15 to dane które pobierze mają wylądować w (*curl_results)[14] ( numeracja od 0 rzecz jasna). Jeśli w funkcji curl_setopt( , WRITEDATA, &plik) ustawię adres do pliku to wszystko ładnie śmiga tylko dane w pliku są po prostu rozwalone(nie po kolei, pozamieniane itd) - w zależności od tego jak, kiedy i z jaką prędkością curl pobierze dane.

Chce trzymać te rezultaty w pamięci ponieważ muszę je poddać dalszej obróbce.

Dlaczego w write_to_memory mogę pobrać zawartość pól w strukturze natomiast zwiększyć pamięć danemu polu już nie ?
Dzięki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1