C-strul, löst efter några timmar...

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
ie
EF Sponsor
Inlägg: 1371
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

C-strul, löst efter några timmar...

Inlägg av ie »

Råkade ut för något märkligt idag...

Jag har ett C-program som jag körde på en Ubuntu 8-server. Nu har jag flyttat över (och komplierat om) programmet till en Ubuntu 14.4-server så får jag plötsligt fel i programmet. Efter att ha tagit bort allt oväsentligt så fick jag kvar följande kod:

Kod: Markera allt

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

double difftimet(t1,t2)
struct tm *t1,*t2;
{
	time_t tt1, tt2;

	tt1=mktime(t1);	
	tt2=mktime(t2);
	return difftime(tt1,tt2);	
}

main()
{
	struct tm timemes, timeper;

	timeper.tm_year=0;
//	timeper.tm_mon=10;
//	timeper.tm_mday=13;
//	timeper.tm_hour=21;
//	timeper.tm_min=0;
//	timeper.tm_sec=0;

	timemes.tm_year=2014;
	timemes.tm_mon=10;
	timemes.tm_mday=13;
	timemes.tm_hour=21;
	timemes.tm_min=0;
	timemes.tm_sec=0;

	printf("<1: %f, %d>\n",difftimet(&timeper,&timemes),timeper.tm_year);
	printf("<2: %f, %d>\n",difftimet(&timeper,&timemes),timeper.tm_year);
}
Som synes så tilldelar jag inte några värden till ett antal members i den första structen. Det var avsiktligt då jag utnyttjade "timeper.tm_year=0" som en flagga för att visa att variablen inte var satt ännu.

"difftimet" används för att visa skillnaden i sekunder mellan de båda variablerna. Det gör inte mig något att funktionen ger ett "slumpmässigt" värde beroende på innehållet i de oinitierade variablerna.

Det konstiga i det hela är dock att "timeper.tm_year" byter värde när jag kör "difftimet".

Kod: Markera allt

ie@jupiter:~/c/test$ ./logtest
<1: -61498523684.000000, 0>
<2: -61498523684.000000, 66>
Som synes visar "difftimet" samma resultat båda gångerna men värdet i variabeln "timeper.tm_year" har ändrats. Värdet - 66 i detta fall - är samma vid varje körning men blir något annat vid en ny kompilering.

Det räcker med att jag initierar "timeper.tm_sec" för att det ska fungera som förväntat (kom jag på efter några timmar).

Har svårt att förstå "att minne skrivs över" (eller vad det nu är för fel), bara för att en variabel är oinitierad.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46916
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: C-strul, löst efter några timmar...

Inlägg av TomasL »

Oinitierade varaiabler skall inte förekomma,
If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.
Vilket i praktiken innebär att slumpen avgör vad som händer.
swp
Inlägg: 63
Blev medlem: 31 december 2010, 00:54:56

Re: C-strul, löst efter några timmar...

Inlägg av swp »

Det är antagligen mktime() som modifierar innehållet pga av det som står i de oinitierade fälten.
The mktime() function modifies the fields of the tm structure as follows: tm_wday and tm_yday are set to values determined from the contents of the other fields; if structure members are outside their valid interval, they will be normalized (so that, for example, 40 October is changed into 9 November); tm_isdst is set (regardless of its initial value) to a positive value or to 0, respectively, to indicate whether DST is or is not in effect at the specified time. Calling mktime() also sets the external variable tzname with information about the current timezone.
Skriv svar