Comment memcpy travail sur les pointeurs de tableaux?
J'ai initialiser 2 tableaux comme suit:
x = (double*) malloc(sizeof(double)*n);
xPlus1 = (double*) malloc(sizeof(double)*n);
Tout d'abord, je ne suis pas certain de ce que x ou xPlus1 maintenant, un pointeur vers un tableau de double, ou un tableau de pointeurs vers des doubles? :/
La réponse à cette question probablement des effets de cela, mais si je fais ces diverses opérations, je n'arrive pas à faire ce que je veux, qui est juste à copier les valeurs d'xPlus1 dans x. xPlus1 et x ont des valeurs différentes pour chaque indice, parce que l'impression après une simple boucle for obtient l'effet désiré:
for (int i = 0; i < n; i++) {
x[i] = xPlus1[i];
}
Mais à l'aide de...
memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x));
Si j'ai accès x après l'un de ces, dans la même fonction, x est inchangé, de même conservé ses anciennes valeurs.
memcpy(&x, &xPlus1, sizeof(x));
Je crois que cela fait x et xPlus1 pointer vers le même emplacement de mémoire par les produits que je reçois. C'est parce que si je modifie x ou xPlus1 après cette copie, puis les deux valeurs de changer si je imprimer les deux tableaux.
memcpy(&x, xPlus1, sizeof(x));
Meurt, exception: exception non Gérée à 0x011D5626 dans MPITemplate.exe: 0xC0000005: violation d'Accès de l'écriture de l'emplacement 0x00000000.
L'esperluette dans les fonctions indiquent généralement un passage par référence, quelle est la situation lorsqu'il est administré à memcpy, et quelle différence cela fait-il si c'est pour écrire sur les mêmes blocs à la fin?
Je vous en serais reconnaissant si quelqu'un pouvait me dire en détail ce qu'il se passe avec ces opérations, parce que je peux bidouiller pour le faire fonctionner, mais je préfère comprendre ce qui se passe réellement lorsque ces appels sont effectués.
Merci,
Mike
xPlus1
est DÉJÀ un pointeur vers la fonction malloc avais de la mémoire. lorsque vous ne&xPlus1
vous obtenez l'adresse du pointeur lui-même, PAS le malloc avais de la mémoire. par exemple, vous n'êtes pas de copie dans votre malloc bloc, vous les copiez dans où le pointeur existe et bousiller tout autre chose qui vient après lui.- avez-vous essayé
memcpy(x, xPlus1, n * sizeof(double));
? - x est un
double
pointeur pointant sur un bloc de mémoire alloué pourn
éléments doubles.xplus1
est également faire le même, mais ils sont dans différents emplacements de mémoire. si vous imprimez les adresses pour tous lesx
s etxplus1
s, vous verrez qu'ils sont tous différents. Si vous utilisez des &x comme argument, vous êtes à l'aide du pointeur de pointeur, ce qui n'est pas correct. L'exception que vous avez obtenu est fondamentalement vous dire que, parce que vous avez été la copie et de l'écriture et de la lecture à partir du même emplacement simultanément, vous avez des problèmes d'accès. - Je reçois les pointeurs de pointeurs à défaut puis, je suppose que c'est juste de la chance qu'il ne tue pas le programme lorsque j'utilise memcpy(x, &xPlus1, sizeof(x)); je pense donc que c'est à l'aide de la taille du pointeur de la 'x' lorsque je place sizeof(x) n'est pas la taille du tableau il des points de? Je vais essayer à l'aide de n * sizeof(double)
- la chance est simplement une consolation. si vous regardez la documentation de memcpy, il dit
void * memcpy ( void * destination, const void * source, size_t num );
vous pouvez clairement voir que lesmemcpy(x, xPlus1, sizeof(x))
est bon pour vous. Aussi, leconst source
bits signifie que votre source de données n'est pas modifié, ce qui vous l'a fait et d'avoir l'erreur de violation d'accès lorsque vous avez essayé de pointeur de pointeur. - À toutes fins utiles,
memcpy
se comporte exactement de la même manière, si vous passez un pointeur (qui est ce quex
etxPlus1
sont), ou d'un tableau. Tout simplement parce que les tableaux de désintégration dans les pointeurs lorsqu'il est passé à des fonctions. Votre pointeurs point à un bloc de mémoire alloué à l'aidemalloc
, ce bloc peut être traitée comme un tableau, donc, de copier le contenu de la mémoirex
points dexPlus1
, vous avez simplement à fairememcpy(xPlus1, x, n*sizeof *x);
- BTW: Ne jette pas le résultat de
malloc()
- Devrait avoir mentionné que je suis en train d'écrire en C++, j'ai eu une lecture de la question, je ne pense pas que je peux le contourner en C++ comme dans le fichier d'en-tête x est déclaré comme un pointeur vers un double (double*)
- Juste assez. Mais alors, pourquoi
malloc()
en premier lieu? - Bon point, je vois il y a d'autres façons d'initialiser les tableaux en C++, même avec les entrées dynamiques (bien qu'il semble que si je veux variable tailles pas connu au moment de l'exécution pour les deux dimensions du tableau, j'avais besoin de boucle), est-il un avantage par rapport à l'aide de malloc vraiment bien? J'ai fait presque toute ma programmation en C#, donc n'ai pas rencontré de cette baisse de niveau de type de codage avant de vraiment.
- Il y a des. Sauf si vous êtes sûr à 100% que vous savez exactement ce que vous faites et pourquoi, ne pas utiliser de
malloc()
. Utiliser lesnew
- similaire à C#, à l'exception que vous avez à gérer la mémoire. Mieux encore, utiliser lesstd::make_unique
etstd::make_shared
selon le cas. Encore mieux (dans la mesure du raisonnable): utilisation de la pile par défaut de l'allocation et de copier les valeurs. Ne pas utiliser des tableaux, utiliserstd::vector
etstd::array
. new
initialise l'objet. C'est aussi plus de type sécurisé, et permet à l'allocateur de faire son travail plus efficacement. Voir ici: parashift.com/c++-faq/new-vs-malloc.html
Vous devez vous connecter pour publier un commentaire.
Non, vous ne le sont pas. Vous n'avez pas montrer
x
etxPlus1
définition, mais si ils sont des tableaux comme:votre code ne compile pas. Donc, en supposant que votre code compile
x
etxPlus1
sont pointeurs à double. Ils sont proches, mais pas de la même chose.De nouveau que vous devriez publier leur définition, et ensuite votre question n'aurait pas de sens. Ils sont des pointeurs et tout ce que vous affectez de ne pas changer ce fait. Ils sont donc des pointeurs de la tenue de l'adresse de la taille du bloc de mémoire
sizeof(double) * n
. Ce sera dans ce mémoire dépend de vous, vous pouvez le traiter comme tableau de double, ou quelque chose d'autre qui a une taille inférieure ou égale àsizeof(double) * n
.Donc la première ligne de code copies sizeof( double * ) probablement 8 octets, c'est à dire une double (qui est juste coincedence que sur la plate-forme 64 bits sizeof( double * ) == sizeof( double ) ) à partir de la mémoire pointée par
xPlus1
à la mémoire pointée parx
. Donc en gros, vous avez copié un élément et que la même chose que (si vous êtes en 32 bits plate-forme vous suffit de copier de la moitié de la double):Deuxième ligne copiés de la mémoire où le pointeur de la
xPlus1
situé à bloc de mémoire pointée parx
. Si vous avez copiédouble *
àdouble
x[0], qui ne fait pas beaucoup de sens:Ce code:
essentiellement fait (juste alambiqué façon):
Code suivant:
est équivalent à ceci:
qui rend
x
pointeur d'avoir des ordures adresse qui conduit à une exception.De sorte que votre code doit être:
Les deux
x
etxPlus1
doit être de typedouble*
. Ils sont des pointeurs vers un tableau den
doubles.Donc, quand vous faites cela:
Depuis
x
est juste undouble*
, que seules les copiessizeof(double*)
octets... qui est-à-dire, 8. Ce que vous voulez faire est:parce que le type de
*x
estdouble
, doncn * sizeof(*x)
sera le nombre total d'octets de mémoire quexPlus1
propriétaire:n
double
s.x[0]
se trouve être... peu importe, ces 8 octets sera validedouble
valeur - peut-être que votre travail est tout simplement arrivé de ne pas modifier la baisse de 4 octets.Vous laissé de côté les déclarations.
Ajout du type, de la
rend plus claire que
x
est un pointeur vers unedouble
.Dans ce cas particulier, le double
x
est le premier élément d'un tableau den
doubles.Quelque chose comme ceci:
&x
serait de vous donner l'adresse de la variablex
lui-même. C'est très différent de l'adresse de la variablex
contient.(Si vous avez
int x = 1;
,&x
ne sera probablement pas être 1.)memcpy
prend deux pointeurs, l'un pour la destination et une pour la source, et la taille de la mémoire à copier.Mais
sizeof(x)
ne vous donne pas la taille du tableau que vous avez alloué; il vous donne la taille dex
, qui est un pointeur.(La taille est mesurée en multiples de
sizeof(char)
, qui, par définition, est 1, etsizeof(double*)
sera 4 (32 bits) ou 8 (64 bits) sur la plupart des machines modernes. Si vous êtes à la copie de 32 ou 64 bits.)Le paramètre de taille doit être de la même taille que vous avez passé à
malloc
, si vous souhaitez copier la totalité de la chose.Les pointeurs doivent être ceux retourné à partir de
malloc
, puisque ce sont les blocs de mémoire que vous souhaitez copier.Donc,
devrait fonctionner comme prévu.