Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.12.2007, 16:35   #1
Anil
 
Регистрация: 04.12.2007
Сообщений: 4
По умолчанию загрузка и выгрузка памяти на языке СИ

Помогите, как в языке Си выделить память и удалить её (malloc, free)?
Как удалить элемент массива? Если записыватся массив, а необходимо выбрать определенный элемент и удалить его(ссылка на этот элемент должна быть удалена).Соответствено, после удаления должно произойти смещение элементов.
Anil вне форума Ответить с цитированием
Старый 14.12.2007, 17:09   #2
theos
Форумчанин
 
Аватар для theos
 
Регистрация: 10.12.2007
Сообщений: 158
По умолчанию

По возможности rtfm. И гугл в помощь )) Почитай ещё о Standart Template Library - там удобно реализованы удобные классы динамических массивов и других структур данных.

Если будешь делать сам, то для изменения длинны выделенного участка памяти (без потери информации) есть функция realloc. Сначала сдвигаешь конец массива (через цикл), а потом меняешь размер.

А вообще, если ты пишешь на с++, лучше используй new и delete. Они написаны через malloc и free, но имеют некоторые бонусы. Напр. возвращают типизированный указатель, а не void*.
theos вне форума Ответить с цитированием
Старый 17.12.2007, 15:45   #3
Anil
 
Регистрация: 04.12.2007
Сообщений: 4
Радость

Цитата:
Сообщение от theos Посмотреть сообщение
По возможности rtfm. И гугл в помощь )) Почитай ещё о Standart Template Library - там удобно реализованы удобные классы динамических массивов и других структур данных.

Если будешь делать сам, то для изменения длинны выделенного участка памяти (без потери информации) есть функция realloc. Сначала сдвигаешь конец массива (через цикл), а потом меняешь размер.

А вообще, если ты пишешь на с++, лучше используй new и delete. Они написаны через malloc и free, но имеют некоторые бонусы. Напр. возвращают типизированный указатель, а не void*.
Привет, дело в том,что прога должна быть написана на Си, new и delete не подходит.Вот тут нужно исправить\
Ошибка в функции удаления. Удаляется nItem - 1 элемент, ссылка на этот удаленный элемент так и остается в массиве, а требуется удалить элемент nItem. Вы затираете ссылку на элемент nItem при переписи массива. Это значит что память, выделенная под него не освобождается. Надо исправить.

Код:
if( (nItem >=0) && (nItem < nChasy) )
 {
  for(i = nItem; i < nChasy; i++)
  {
   aChasy[i] = aChasy[i+1];
  }
  if(aChasy[nItem - 1].nType == CHASY_STENA)
   free(aChasy[nItem - 1].pChasy);
  else
   free(aChasy[nItem - 1].pChasy);
  nChasy--;

  return SC_OK;
 }
Модератор: Испоьзуйте тег <CODE> что бы ваши посты были более красивы и читабельны.

Последний раз редактировалось merax; 20.12.2007 в 07:27.
Anil вне форума Ответить с цитированием
Старый 17.12.2007, 19:08   #4
theos
Форумчанин
 
Аватар для theos
 
Регистрация: 10.12.2007
Сообщений: 158
По умолчанию

Какого типа массив aChasy? Небось структура какая-то )) Тогда в aChasy[nItem] (!!! заметь, ты удаляешь не тот элемент) перед(!) сдвигом надо освободить память у атрибутов структуры, для которых ты её уделял. Во время сдвига пропадёт сам элемент, а потом ты просто изменяешь размер массива. (пропадает последний).

Это должно выглядеть примерно так:

Код:
if( (nItem >=0) && (nItem < nChasy) )
{
   // тут удаляем всё, что было динамически
   // выделено в aChasy[i]
   for(i = nItem; i < nChasy; i++)
      aChasy[i] = aChasy[i+1];

   aChasy = (/*тип aChasy*/ *)realloc(aChasy, sizeof(/*тип aChasy*/) * (-- nChasy));

   return SC_OK;
}
theos вне форума Ответить с цитированием
Старый 18.12.2007, 14:32   #5
Anil
 
Регистрация: 04.12.2007
Сообщений: 4
По умолчанию

Структура это, могу для примера весь код дать
//Work1.c

Код:
#include <windows.h>
#include "Work1.h"

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, 
	LPVOID lpReserved)
{
	/*
	switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
		break;
	}*/
	return TRUE;
}

Chasy aChasy[MAX_ID];
long nChasy = 0;


//
WORK1_API long	WINAPI ChasyCount(long* pCount)
{
	*pCount = nChasy;
	return SC_OK;
}

WORK1_API long WINAPI ChasyItem(long nItem, Chasy* pChasy)
{
	long nRet = SC_OK;
	
	if( (nItem >=0) && (nItem < nChasy) ) 
	{
		pChasy->nType	 = aChasy[nItem].nType; 
		pChasy->pChasy = aChasy[nItem].pChasy;		
	}
	else
		nRet = SC_ERROR;
	
	return nRet;
}

WORK1_API long	WINAPI ChasyRemove(long nItem)
{
	int i;

	if( (nItem >=0) && (nItem < nChasy) ) 
	{
		for(i = nItem; i < nChasy; i++)
		{
			aChasy[i] = aChasy[i+1];
		}
		if(aChasy[nItem - 1].nType == CHASY_STENA)
			free(aChasy[nItem - 1].pChasy);
		else
			free(aChasy[nItem - 1].pChasy);
		nChasy--;

		return SC_OK;
	}
	else
		return SC_ERROR;

	return SC_ERROR;
}

WORK1_API long	WINAPI StenaNew(Stena* pStena)
{
	long nRet = SC_ERROR;

	Stena* pStenaNew = NULL;

	if( (pStena!= NULL) && (nChasy < MAX_ID)) 
	{
		pStenaNew = malloc(sizeof(Stena));		
		if( pStenaNew != NULL) 
		{
			if
				(
				strcpy(pStenaNew->szTitle, pStena->szTitle) != NULL 
				) 
			{
				pStenaNew->nMexanizm = pStena->nMexanizm;
				pStenaNew->nYear = pStena->nYear; 

				aChasy[nChasy].pChasy = pStenaNew;
				aChasy[nChasy].nType = CHASY_STENA;
				nChasy++;

				nRet = SC_OK;
			} 
			else
				free(pStenaNew);
		}
	}
	return nRet;
}

WORK1_API long	WINAPI RykaNew(Ryka* pRyka)
{

	long nRet = SC_ERROR;

	Ryka* pRykaNew = NULL;

	if( (pRyka != NULL) && (nChasy < MAX_ID)) 
	{
		pRykaNew = malloc(sizeof(Ryka));		
		if( pRykaNew != NULL) 
		{
			if
				(
				strcpy(pRykaNew->szTitle, pRyka->szTitle) != NULL 
				) 
			{
				pRykaNew->nMexanizm = pRyka->nMexanizm;
				pRykaNew->nTsiferblat = pRyka->nTsiferblat; 

				aChasy[nChasy].pChasy = pRykaNew;
				aChasy[nChasy].nType = CHASY_RYKA;
				nChasy++;

				nRet = SC_OK;
			} 
			else
				free(pRykaNew);
		}
	}
	return nRet;
}
и Файл Work1.h
#define WORK1_EXPORTS 

#ifdef WORK1_EXPORTS
#	define WORK1_API	__declspec(dllexport)
#else
#	define WORK1_API	__declspec(dllimport)
#endif

#define WORK1_IMPORT	extern __declspec( dllimport )

#define MAX_LENGTH		100
#define MAX_ID			20

#define SC_OK			0
#define SC_ERROR		1

#define CHASY_STENA	1
#define CHASY_RYKA	2

typedef struct
	{
		char			szTitle[MAX_LENGTH];//Citizen
		long			nMexanizm;
		long            nYear;
	} Stena;

typedef struct
	{
		char			szTitle[MAX_LENGTH];//Bylgary
		long			nMexanizm;
		long			nTsiferblat;
	} Ryka;

typedef struct
	{
		long			nType;
		void*			pChasy;
	} Chasy;

WORK1_API		long	WINAPI	ChasyCount	(long* nCount);
WORK1_API		long	WINAPI	ChastItem	(long nItem, Chasy*);
WORK1_API		long	WINAPI	ChasyRemove	(long nItem);
WORK1_API		long	WINAPI	StenaNew	(Stena*);
WORK1_API		long	WINAPI	RykaNew	     (Ryka*);
Модератор: Испоьзуйте тег <CODE> что бы ваши посты были более красивы и читабельны.

Последний раз редактировалось merax; 20.12.2007 в 07:28.
Anil вне форума Ответить с цитированием
Старый 19.12.2007, 18:25   #6
theos
Форумчанин
 
Аватар для theos
 
Регистрация: 10.12.2007
Сообщений: 158
По умолчанию

Ну так у тебя получается даже память не динамически выделяется )) тогда совсем всё просто. Сдвигаешь элементы и меняешь количество.

Попробуй так:

Код:
WORK1_API long WINAPI ChasyRemove(long nItem)
{
int i;

if( (nItem >=0) && (nItem < nChasy) ) 
{
   if(nChasy[nItem].pChasy) free(nChasy[nItem].pChasy);
   for(i = nItem; i < nChasy; i++)  
      aChasy[i] = aChasy[i+1];  
 
   -- nChasy;  
    return SC_OK;
} else {
   return SC_ERROR;
}
return SC_ERROR;
}
(я остальное правда только мельком пробежал)
theos вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выгрузка картинок в проект Rusl92 Общие вопросы Delphi 2 20.08.2008 23:00
Программа на русском языке в Windows XP на другом языке... Как? 29bit Свободное общение 4 01.02.2008 17:24
Выгрузка в файл с динамическим названием. Квэнди БД в Delphi 0 24.06.2007 15:39
выгрузка в файл zetrix БД в Delphi 0 30.10.2006 12:50