[C] Savoir utiliser Malloc

Résolu/Fermé
Utilisateur anonyme - 8 oct. 2012 à 21:51
 Utilisateur anonyme - 11 oct. 2012 à 14:47
Bonjour à tous,


char * create_date;

if (GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite)) {
	FileTimeToSystemTime(&ftCreate, &stUTC); // Convert the created time to local time. set +1
	SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);

// 	create_date = (char *) malloc(strlen((const char *) stLocal.wDay) + strlen((const char *) stLocal.wMonth) + strlen((const char *) stLocal.wYear) + strlen((const char *) stLocal.wHour) + strlen((const char *) stLocal.wMinute) +1);
						
	sprintf(create_date, "%02d/%02d/%d %02d:%02d\n", stLocal.wDay, stLocal.wMonth, stLocal.wYear, stLocal.wHour, stLocal.wMinute);
}
else {
	create_date = "Create error...";
}


Ici, le code plante au niveau de: "//".

J'aurais aimé des informations sur le pourquoi du comment :-)

Merci,

5 réponses

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
8 oct. 2012 à 22:06
strlen((const char *) stLocal.wDay)
strlen, n'est à utiliser que lorsque tu souhaites connaître le nombre de caractères d'une chaîne de caractères.
stLocal.wDay n'est pas une chaîne, strlen va te retourner n'importe quoi.
Du coup malloc va planter.
Dans ton cas, tu sais exactement la taille que tu veux allouer (il suffit de compter).

create_date = "Create error...";
Surtout pas. Il faut utiliser strcpy. Sinon, tu perds l'allocation réalisée par malloc.
0
Utilisateur anonyme
8 oct. 2012 à 22:27
Dans ton cas, tu sais exactement la taille que tu veux allouer (il suffit de compter). 


Compter cela ? : %02d/%02d/%d %02d:%02d

Surtout pas. Il faut utiliser strcpy. Sinon, tu perds l'allocation réalisée par malloc. 


Oui, mais je n'ai pas réalisé d'allocation dans mon Else, il n'y en a qu'une dans mon If.

Car dans mon Else, la taille n'aura pas à évoluer non ? Donc je peux rester ainsi :-)

(ça y est, je crois enfin avoir compris le but du malloc :-))
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
8 oct. 2012 à 23:48
Compter cela ? : %02d/%02d/%d %02d:%02d
Yes. Soit 15 (enfin revérifie). J'ai supposé que tu voulais mettre %02d (à la place de ton %d). Et je n'ai pas compté le \n que tu as mis. D'ailleurs, je ne vois pas pourquoi tu le mets.
Oui, mais je n'ai pas réalisé d'allocation dans mon Else, il n'y en a qu'une dans mon If.
Certes. Sauf que ce n'est pas une bonne habitude. Dès lors que tu remodifieras le pointeur, la chaîne "Create Error..." sera inaccessible. A moins de recréer la même chaîne en mémoire.
Je te conseille plutôt de faire : const char * const msg="Create Error..."; en début.
Puis : createdate=msg;
Au moins, la chaîne "Create Error..." n'est pas perdue :-).
0
Utilisateur anonyme
9 oct. 2012 à 09:46
Pris en compte, j'ai modifié et ai une autre erreur...

char * create_date;

if (GetFileTime(hFile, &ftCreate, &ftAccess, &ftWrite))	{
	FileTimeToSystemTime(&ftCreate, &stUTC); // Convert the created time to local time. set +1
	SystemTimeToTzSpecificLocalTime(NULL, &stUTC, &stLocal);

	create_date [25];
						
	sprintf((char *) create_date, "%02d/%02d/%d %02d:%02d", stLocal.wDay, stLocal.wMonth, stLocal.wYear, stLocal.wHour, stLocal.wMinute);
}
else {
	create_date = "Create error...";
}


Et j'ai ceci:

http://puu.sh/1cWya

Merci pour le const msg, je m'en servirai mais ici il ne m'aidera pas beaucoup, c'est pratique :-)
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
9 oct. 2012 à 18:52
Oh non, ne me fais pas cette erreur après tout ce qu'on s'est dit ^^.
create_date [25];
Cela ne fait rien.
Petit cours :
L'allocation d'un tableau est soit :
statique : type nom[TAILLE]; exemple char create_date[25]; (et se fait seulement à la déclaration (statique)).
dynamique : type *nom; exemple char *create_date; (à faire une seule fois à la déclaration). Mais par la suite, tu peux changer la taille avec malloc (n'oublie pas de libérer la mémoire allouée à chaque fois que tu ne l'utilises plus (free)).

Aucune autre façon n'est tolérée en C. Et tu ne peux pas mélanger les deux. Tu dois te décider dès la déclaration de la variable.

Si tu fais create_date[25] cela, va récupérer le 26ème caractère (la chaîne commence à 0). Aucune allocation n'est faite.
0
Utilisateur anonyme
9 oct. 2012 à 18:59
create_date = (char *) malloc(25);


Faut que ça rentre c'est tout :-)

En fait, j'ai voulu faire comme sur la doc', ça m'apprendra...

Merci encore pour ton aide !!

A bientôt :)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
11 oct. 2012 à 14:47
Coucou Fiddy,

J'aurais aimé savoir, c'est bon ça ? :

char _GetACL() {

	DWORD dwRtnCode = 0;
	PSID pSidOwner = NULL;
	BOOL bRtnBool = TRUE;
	LPTSTR AcctName = NULL;
	LPTSTR DomainName = NULL;
	DWORD dwAcctName = 1, dwDomainName = 1;
	SID_NAME_USE eUse = SidTypeUnknown;
	PSECURITY_DESCRIPTOR pSD = NULL;
	DWORD dwErrorCode;
	char * acls_get;

// Get the owner SID of the file.
	dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL,NULL, NULL, &pSD);

// Check GetLastError for GetSecurityInfo error condition.
	if (dwRtnCode != ERROR_SUCCESS) {
		acls_get = (char *) malloc(25);
		sprintf(acls_get, "GetSecurityInfo error: %d", GetLastError());
		return ((char) acls_get);
	}

// First call to LookupAccountSid to get the buffer sizes.
	bRtnBool = LookupAccountSid(
		  NULL,           // local computer
		  pSidOwner,
		  AcctName,
		  (LPDWORD)&dwAcctName,
		  DomainName,
		  (LPDWORD)&dwDomainName,
		  &eUse);

// Reallocate memory for the buffers.
	AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName);

// Check GetLastError for GlobalAlloc error condition.
	if (AcctName == NULL) {
		acls_get = (char *) malloc(25);
		sprintf(acls_get, "GlobalAlloc error: %d", GetLastError());
		return ((char) acls_get);
	}

DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName);

// Check GetLastError for GlobalAlloc error condition.
	if (DomainName == NULL) {
		acls_get = (char *) malloc(25);
		sprintf(acls_get, "GlobalAlloc error: %d", GetLastError());
		return ((char) acls_get);
	}

// Second call to LookupAccountSid to get the account name.
	bRtnBool = LookupAccountSid(
	  NULL,                   // name of local or remote computer
	  pSidOwner,              // security identifier
	  AcctName,               // account name buffer
	  (LPDWORD)&dwAcctName,   // size of account name buffer 
	  DomainName,             // domain name
	  (LPDWORD)&dwDomainName, // size of domain name buffer
	  &eUse);                 // SID type

	if (bRtnBool == FALSE) {
		  dwErrorCode = GetLastError();

		  if (dwErrorCode == ERROR_NONE_MAPPED) {
			  acls_get = (char *) malloc(45);
			  sprintf(acls_get, "Account owner not found for specified SID");
			  }
		  else {
			  acls_get = (char *) malloc(30);
			  sprintf(acls_get, "Error in LookupAccountSid: %d", dwErrorCode);
		  }
		  return ((char) acls_get);
	} 
	else if (bRtnBool == TRUE) {
		acls_get = (char *) malloc(strlen((const char *) AcctName));
		sprintf(acls_get, "%s", AcctName);
	}			

	printf("%s", acls_get);
	system("pause");
return ((char) acls_get);
}


Je modifie ma variable avec les bonnes allocations en mémoire :-)
0