Problem z działaniem memset.

0

Mam problem z czyszczeniem tablicy dwuwymiarowej memsetem. Mam coś takiego:

memset(ttwod, 0, lmiast*lmiast*sizeof(int));

Czy to wypełni całą tablicę zerami? Szukałem u wujka G, ale nie do końca rozumiem działanie i składnię memsetu. Czy moglibyście mi to przybliżyć?

1

void * memset ( void * ptr, int value, size_t num );
ptr Pointer to the block of memory to fill.
value Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.
num Number of bytes to be set to the value.

Co znaczy że:

memset(ttwod, 0, lmiast*lmiast*sizeof(int));

spowoduje wypełnienie tablicy ttwod od pierwszego elementu do elementu lmiastlmiast wartością 0 (bardziej poprawnie: lmiastlmiast*sizeof(int) bajtów od miejsca na które wskazuje ttwod zostanie wypełnione 0)

0

Czyli cała tablica ttwod od [0][0] do [max][max] zostanie wypełniona zerami? W moim kodzie coś nie działa, tak jakby niektóre wartości nie były zerami...

0

a nie masz czasem tablicy dynamicznej w kodzie?

0

To jest początek kodu:

 #include <iostream>
#include <list>
#include <cstring>
#define lli long long int
using namespace std;
int main() 
{
    int lmiast, ldrog;
    cin >> lmiast;
    cin >> ldrog;
    int zmiasta, domiasta;
    lli lpowiazan=0;
    int ttwod[lmiast][lmiast];
    memset(ttwod, 0, lmiast*lmiast*sizeof(int));

Właściwie powinno być:

#include <iostream>
#include <list>
#include <cstring>
#define lli long long int
using namespace std;
int main() 
{
    int lmiast, ldrog;
    cin >> lmiast;
    cin >> ldrog;
    int zmiasta, domiasta;
    lli lpowiazan=0;
    lli ttwod[lmiast+1][lmiast+1];
    memset(ttwod, 0, lmiast+1*lmiast+1*sizeof(lli)); 

Ale jak później dodam coś takiego:

   for (int i=0; i!=ldrog; i++)
    {
        cin >> zmiasta;
        cin >> domiasta;
        ttwod[zmiasta][domiasta]++;
        cout << ttwod[zmiasta][domiasta]<<"TOTO" <<endl;
    }

cout w celu sprawdzenia wyników, to dla pojedynczych ++ w pierwszym sypie się trochę (czasami jest np. zamiast 1 po dodaniu to wyskakuje ciąg cyfr). W drugim zawsze wyskakuje ten ciąg.

0

cin >> lmiast;
lli ttwod[lmiast+1][lmiast+1];

który kompilator pozwala na taką herezję?

0

Każdy zgodny ze standardem, ale lepiej tego nie używać.

1

Ja to robię tak:

short** mImageFrame = new short*[mFrameWidth]; // tablica wskaźników
for (int i = 0; i < mFrameWidth; i++)
{
    mImageFrame[i] = new short[mFrameHeight];
    for (int j = 0; j < mFrameHeight; j++)
        mImageFrame[i][j] = 0;
}

Analogiczne dopasuj do swojego kodu. Możesz jeszcze skorzystać z biblioteki vector.

Aha, i jeszcze na końcu trzeba do zniszczyć:

for (int i = 0; i < mFrameWidth; i++)
    delete mImageFrame[i];
delete mImageFrame;
0

Zrobiłem tak, działa:

 #include <iostream>
#include <list>
#include <cstring>
using namespace std;
int main() 
{
    int lmiast, ldrog;
    cin >> lmiast;
    cin >> ldrog;
    int lpowiazan=0, zmiasta, domiasta;    
    short** ttwod = new short*[lmiast+1];
    for (int i=0; i<lmiast+1; i++)
	{
   		 ttwod[i]=new short[lmiast+1];
   		 for (int j=0; j<lmiast+1; j++)
     	             ttwod[i][j]=0;
	}
0

W ten sposób jak usuniesz @michalo2882 to masz wyciek pamięci, bo usuwasz tylko początkowe obiekty tablic. Powinno być delete [] tak w pętli for jak i poza nią.

0

Jak się deklaruje tablicę (a nie wskaźnik do tablicy!), to najlepiej przy wszystkich wielkościach używać sizeof(tablica), zmniejsza ryzyko błędu. Przy tym rozwiązaniu (tablice na stosie ze zmiennym rozmiarem) trzeba się zastanowić nad przenośnością kodu (wykorzystuje się rozszerzenie kompilatora) i upewnić się, czy tablica nie może być za duża (odradzałbym stosowanie tablic więcej niż jednowymiarowych. Z drugiej strony taka deklaracja tablicy pomocniczej jest wg mnie czytelniejsza i eliminuje ryzyko wycieku pamięci

0

zamiast tej petli wewnętrznej:
for (int j=0; j<lmiast+1; j++)
ttwod[i][j]=0;

Możesz wpisać:
memset(ttwod[i], 0, sizeof(short) * (lmiast+1));

Btw. tablicy z dwoma wymiarami (i wiecej) nie da sie zerować jednym memset bo nie masz gwarancji ciągłości pamięci, możesz tylko jeden wymiar w ten sposób wyzerować(najbardziej z prawej).

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