Forum: PC-Programmierung strndup() bekommt keinen Speicher mehr


von Erwin M. (nobodyy)


Lesenswert?

Bei dem Programm dupmerge, von 
https://sourceforge.net/projects/dupmerge/files/, habe ich unter Ubuntu 
18.10 das Problem, das strndup() nicht mehr genügend Speicher bekommt 
und Null-Pointer zurückgibt.

Das tritt auf an der Stelle, an der die Dateinamen in Datenfelder 
eingelesen werden:
1
    if ((NULL == (names[i] = strndup (buf, BUFSIZ))) or (NULL == (a_names[i] = strndup (buf, BUFSIZ))))
2
    {                         
3
      (void) fprintf (stderr, "%s: Out of memory, ((NULL == (names[i] = strndup (buf, BUFSIZ))) or (NULL == (a_names[i] = strndup (buf, BUFSIZ))))\n", argv[0]);
4
      (void) fprintf (stderr, "  i=%d, j=%d, names[i]=%p, a_names[i]=%p\n", i, j, names[i], a_names[i]);
5
      exit (1);
6
    }

Dort zeigt sich, mit einem zusätzlichen printf():

dupmerge: Out of memory, ((NULL == (names[i] = strndup (buf, BUFSIZ))) 
or (NULL == (a_names[i] = strndup (buf, BUFSIZ))))
i=29909, j=35, names[i]=(nil), a_names[i]=(nil)

Also bei circa 1 MB ist plötzlich Schluß, auch für root, obwohl das 
letztes Jahr noch funktionierte.
free zeigt mir aber reichlich freien Speicher:

              Gesamt   belegt    frei        gemns. Puffer/Cache 
verf�gbar
Speicher:    65709980     6917308    10054464     1091276    48738208 
57026856
Auslagerungsspeicher:     2097148           0     2097148

Wieso bekommt strndup keinen Speicher mehr und wie bekomme ich das Limit 
wieder weg?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Was sagt
1
ulimit -a

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Und wie groß ist BUFSIZ?

von Noch ein Tipp (Gast)


Lesenswert?

Wie viel Speicher das Programm verwendet, lässt sich recht einfach 
heraus finden.

strace -e trace=memory meinprogramm

von Erwin M. (nobodyy)


Lesenswert?

Frank M. schrieb:
> Was sagt
>
1
> ulimit -a
2
>

> ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 256008
max locked memory       (kbytes, -l) 16384
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 256008
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Sowohl für User als auch root.

von Erwin M. (nobodyy)


Lesenswert?

Rufus Τ. F. schrieb:
> Und wie groß ist BUFSIZ?

In /usr/include/stdio.h ist es:

#define BUFSIZ 8192

von Noch ein Tipp (Gast)


Lesenswert?

Früher, bei 32Bit, gab es das Problem, mmap() blendete so viel Speicher 
in den Adressbereich ein, dass brk() einen Fehler lieferte, obwohl noch 
genug vorhanden war.

von Erwin M. (nobodyy)


Lesenswert?

Es zeigte sich, das der Fehler von einer ganz anderen Stelle kommt, eine 
Inline-Funktion zum Initialisieren.
Wird das inline entfernt, ist der Fehler weg.
Der GCC reagiert in letzter Zeit allergisch auf Inline-Funktionen, meist 
mit dem Symptom das der Linker sie nicht findet, bei ganz anderen 
Programmen.

von Uhu U. (uhu)


Lesenswert?

Erwin M. schrieb:
> Der GCC reagiert in letzter Zeit allergisch auf Inline-Funktionen, meist
> mit dem Symptom das der Linker sie nicht findet, bei ganz anderen
> Programmen.

Kann er auch nicht, weil Inline-Funktionen vom Compiler i.W. durch 
kopieren behandelt werden.

von Erwin M. (nobodyy)


Lesenswert?

Uhu U. schrieb:
> Erwin M. schrieb:
>> Der GCC reagiert in letzter Zeit allergisch auf Inline-Funktionen, meist
>> mit dem Symptom das der Linker sie nicht findet, bei ganz anderen
>> Programmen.
>
> Kann er auch nicht, weil Inline-Funktionen vom Compiler i.W. durch
> kopieren behandelt werden.

Also nach Kopieren, was ja durch die Inline-Deklaration korrekt ist, ist 
die Funktion assimiliert und nicht mehr zu linken. Damit sollte der 
Linker keine Spur mehr davon sehen. Also irgendwo ist da ein Fehler und 
den bekomme ich nur durch Entfernen der inline-Deklaration weg, wobei 
die über 10 Jahre lang problemlos waren.
Die inline-Deklaration lasse ich deshalb lieber weg.

: Bearbeitet durch User
von Uhu U. (uhu)


Lesenswert?

Erwin M. schrieb:
> Damit sollte der Linker keine Spur mehr davon sehen.

Aber nur, wenn sie static inline deklariert ist - das ist eine Eigenart 
des gcc. Siehe https://www.geeksforgeeks.org/inline-function-in-c/

: Bearbeitet durch User
von Erwin M. (nobodyy)


Lesenswert?

Uhu U. schrieb:
> Erwin M. schrieb:
>> Damit sollte der Linker keine Spur mehr davon sehen.
>
> Aber nur, wenn sie static inline deklariert ist - das ist eine Eigenart
> des gcc. Siehe https://www.geeksforgeeks.org/inline-function-in-c/

Aha, das erklärt es, danke.
Vorher funktionierte es aber 15 Jahre lang problemlos.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.