Domanda

l'indizio è nel titolo, ma fondamentalmente ho ereditato del codice che ha oltre 800 istanze di strcpy.Voglio scrivere una nuova funzione e quindi sostituire strcpy con strcpy_mine.

Quindi sto cercando di capire quale elenco di parametri avrà strcpy_mine.

Ho provato:

void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
  const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
  strncpy( pTarget, pCopyMe, lenAlwaysFour );

  //add extra terminator in case of overrun
  pTarget[lenAlwaysFour] = 0;
}

ma la dimensione di è sempre 4 pCopyMe è un puntatore

quello che non voglio fare è sostituire

strcpy (buf, pCopyMe);

con

strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;

qualche idea?(strcpy_l non è disponibile)

saluti

È stato utile?

Soluzione

A seconda di come i call-siti assomigliano, spesso maggior parte dei casi può essere gestito da un semplice modello:

#include <string.h>

template <int bufferSize>
void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe )
{
  strncpy( pTarget, pCopyMe, bufferSize-1 );

  //add extra terminator in case of overrun
  pTarget[bufferSize-1] = 0;
}

int main()
{
  char buf[128];
  strcpy_mine(buf,"Testing");
  return 0;
}

Se si utilizza Microsoft Visual Studio 2005 o più recente, vedere sovraccarichi modello Sicuro per un'implementazione Microsoft.

Altri suggerimenti

sizeof() restituisce la dimensione del tipo, in questo caso const char* const che saranno 4 su macchine a 32 bit.

Penso che tu pensi di volere strlen().Ma questo non è il modo corretto di utilizzare le funzioni strncpy.Hai bisogno della dimensione del produzione buffer per strncpy.

Per risolvere questo problema è necessario esaminare il codice in ciascun sito di chiamata, calcolare la dimensione del buffer di output e passarlo come argomento a strcpy_mine.Se il sito di chiamata per strcpy (o strcpy_mine) non conosce la dimensione del buffer di output, è necessario cercare all'indietro nel codice la posizione che alloca il buffer e passare la dimensione fino al sito strcpy .

Fondamentalmente non è possibile scrivere un drop in sostituzione di strcpy che accetta gli stessi argomenti e spera di evitare i problemi che hanno prodotto strncpy in primo luogo (e sostituzioni migliori oltre a ciò).Puoi creare una funzione che accetta gli stessi argomenti di strncpy, ma garantisce che il risultato abbia terminazione null: guarda l'implementazione di strlcpy() di OpenBSD funzione.Ma il primo passo deve essere quello di cambiare i siti chiamanti per trasmettere la conoscenza della dimensione del buffer di output.

Un po 'periferica, forse, ma dal momento che nessuno ne ha parlato ed è ostentato nel titolo:. Non si può (legalmente) scrivere una funzione globale chiamato strcpy_mine()

Il "namespace" di funzioni il cui nome inizia con str è riservato per la libreria standard. Vedere, per esempio, la risposta accettata a questa domanda .

Si potrebbe utilizzare lo stesso elenco di parametri come strncpy per il vostro strcpy_mine, ma scriverlo in modo che sempre nullo termina il risultato. Non dovrebbe essere molto difficile da fare.

Una sfida, tuttavia, è che alcuni di codice esistente che chiama strcpy () non può conoscere la dimensione del buffer, sia.

Inoltre è possibile utilizzare macroses per evitare molteplici redazioni. O automatizzare la modifica tramite alcuni script.

È sicuramente bisogno di passare la dimensione del buffer di destinazione come parametro, come altre persone hanno detto sopra.

Questa è una specie di off-topic, ma voglio solo far notare che, dopo aver utilizzato strncpy(), è necessario impostare su null l'ultimo carattere del buffer, che ha indice 1 meno rispetto alla lunghezza (non la lunghezza del buffer):

strncpy (buf, pCopyMe, buflen); buf[buflen - 1] = '\0';

In alternativa, è possibile utilizzare strncat() su una stringa vuota, passandolo una lunghezza che è 1 meno, e garantirà a null-terminare la stringa:

buf[0] = '\0'; strncat (buf, pCopyMe, buflen - 1);

Douglas Leeder ha ragione. C'è un limite per l'utilità di sostituire strcpy a meno che non si è disposti a fare il lavoro sporco di passare in un buon, lunghezza del buffer sano di mente ad ogni istanza. Questo è un sacco di lavoro!

La buona notizia è, ne vale la pena! Indietro di qualche anno fa, sono entrato a diversi progetti C ++ che erano in ritardo, buggy, e inaffidabile. Dichiarando strcpy e strlen proibito, e prendendo 2-3 giorni fuori dal progetto di sostituirli con strncpy custom / strnlen, in tutti questi progetti abbiamo improvvisamente potuto correre per giorni invece di ore. Abbiamo anche visto un sacco di stringhe troncate uscire in schermate e file di log. Che ci ha dato gli indizi necessari per rintracciare i problemi di troncamento, precedentemente schiantarsi problemi.

Se non si vuole fare questo, è possibile ottenere un vantaggio molto più piccolo, semplicemente controllando entrambi i parametri pointer di NULL, e limitare la dimensione massima di una copia di stringa e registrare tutte le volte in cui viene raggiunto il limite. non fare uno strlen di uno dei parametri, come strlen sarà lieto di bloccarsi su di voi se la stringa non è propriamente zero finale.

Al giorno d'oggi, i nuovi progetti utilizzano buoni oggetti stringa, ma c'è un sacco di codice legacy là fuori che non lo fa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top